Vim/vi/sed: активировать определенное количество строк из конца файла
Так же, как мы можем удалить (или заменить, или yank и т.д.) 4-ю-6-ю строки с начала файла в vim:
:4,6d
Я хочу удалить (или заменить, или yank и т.д.) 4-й последний до 6-й строки с конца файла. Это означает, что если файл имеет 15 строк, я бы сделал:
:10,12d
Но делать это нельзя, когда они не знают, сколько строк находится в файлах, и я собираюсь использовать его в нескольких файлах. Как это сделать в vim и sed?
Я действительно посмотрел этот пост, но не нашел его полезным.
Ответы
Ответ 1
Ну, используя vim
, вы можете попробовать следующее: это все равно интуитивно понятно:
:$-4,$-5d
Теперь, используя sed
, я не смог найти точный способ сделать это, но если вы можете использовать что-то другое, кроме sed
, здесь идет решение с head
и tail
:
head -n -4 file.txt && tail -2 file.txt
Ответ 2
В Vim вы можете вычесть номера строк из $
, что означает последнюю строку, например. это будет работать в последних трех строках:
:$-2,$substitute/...
В sed это не так просто, потому что он работает с потоком персонажей и не может просто вернуться. Вам нужно было бы сохранить несколько последних видимых строк в пространстве удержания, а в конце потока работать в пространстве удержания.
Вот несколько рецептов из sed1line.txt:
# print the last 10 lines of a file (emulates "tail")
sed -e :a -e '$q;N;11,$D;ba'
# print the last 2 lines of a file (emulates "tail -2")
sed '$!N;$!D'
# delete the last 2 lines of a file
sed 'N;$!P;$!D;$d'
# delete the last 10 lines of a file
sed -e :a -e '$d;N;2,10ba' -e 'P;D' # method 1
sed -n -e :a -e '1,10!{P;N;D;};N;ba' # method 2
Ответ 3
От 4-го до 6-го строк в конце файла: tac
, чтобы отменить файл
tac filename | sed 4,6d | tac
Ответ 4
Вы можете использовать 2 прохода с awk, сначала пройти, чтобы подсчитать количество строк, а второе - для печати или удаления любых строк, например.
awk 'NR==FNR{numLines++;next} {fromEnd = numLines - FNR} fromEnd > 6 || fromEnd < 4' file file
awk 'NR==FNR{numLines++;next} {fromEnd = numLines - FNR} fromEnd < 6 && fromEnd > 4' file file
Ответ 5
Это может сработать для вас (GNU sed):
sed -r ':a;${s/([^\n]*\n){3}//;q};N;7,$!ba;P;D' file
Это работает, создавая движущееся окно из 6 строк в пространстве шаблонов (PS), а затем удаляя первые три из них при встрече с последней строкой.
-
:a
- метка цикла
-
${s/([^\n]*\n){3}//;q}
удалите первые три строки PS в конце файла и закройте.
-
N
добавьте новую строку, а затем следующую строку в PS.
-
7,$!ba
', если не строки 7
в $
(конец файла), которые являются строками от 1
до 6
, вернитесь к началу, т.е. наклейте :a
-
P;D
для диапазона строк от 7
до $
(конец файла) напечатайте до первой новой строки в PS, а затем удалите до и включите первую новую строку и начните новый цикл.
Предложение Second-last по умолчанию создает окно по умолчанию в том, что строки 1
до 6
добавляются в PS. Начиная с строки 7
до конца строка добавляется в конце, а первая строка печатается и удаляется.
В качестве альтернативы:
sed -e ':a' -e '$s/\([^\n]*\n\)\{3\}//' -e '$q' -e 'N' -e '7,$!ba' -e 'P' -e 'D' file