Использование sed для удаления указанных c строк после последнего появления шаблона - PullRequest
0 голосов
/ 03 апреля 2020

У меня есть файл, который выглядит следующим образом:

this name
this age

Remove these lines and space above.
Remove here too and space below

Keep everything below here. 

Я не хочу жестко кодировать 2, поскольку количество строк, содержащих «this», может измениться. Как я могу удалить 4 строки после последнего вхождения строки. Я пытаюсь sed -e '/this: /{n;N;N;N;N;d}', но он удаляется после первого вхождения строки.

Ответы [ 3 ]

3 голосов
/ 03 апреля 2020

Не могли бы вы попробовать следующее.

awk '
FNR==NR{
  if($0~/this/){
    line=FNR
  }
  next
}
FNR<=line || FNR>(line+4)
'  Input_file Input_file

Вывод будет следующим с показанными образцами.

this: name
this: age
Keep everything below here.
0 голосов
/ 04 апреля 2020

Это может работать для вас (GNU sed):

sed -E ':a;/this/n;//ba;$!N;$!ba;s/^([^\n]*\n?){4}//;/./!d' file 

Если пространство шаблона (PS) содержит this, выведите PS и извлеките следующую строку.

Если следующая строка содержит this repeat.

Если текущая строка не является последней строкой, добавьте следующую строку и повторите.

В противном случае удалите первые четыре строки PS и напечатайте остаток.

Если PS не пуст, в этом случае удалить PS полностью.

NB. Этот файл читается только один раз. Также ОП говорит:

Как я могу удалить 4 строки после последнего вхождения строки

Однако в этом примере может показаться, что 5 строк будут удалены.

0 голосов
/ 04 апреля 2020

Вы также можете использовать это незначительное изменение, чтобы заставить работать вашу исходную команду sed.

sed '/^this:/ { :k ; n ; // b k ; N ; N ; N ; d }' input_file

Используется al oop, который печатает текущую строку и читает следующую (n), пока она продолжает сопоставлять регулярное выражение (пустое регулярное выражение // напоминает последнее оцененное, то есть /^this:/, а команда b k возвращается к метке k в совпадении). Затем вы можете добавить следующие 3 строки и удалить все пространство шаблона, как вы это сделали.

Другая возможность, более краткая, с использованием GNU sed, может быть такой.

sed '/^this:/ b ; /^/,$ { //,+3 d }' input_file

Эта распечатывает любую строка, начинающаяся с this: (b без метки, переходит непосредственно к следующему циклу строки после действия печати по умолчанию).

На первой строке не соответствует this:, две вложенные диапазоны срабатывания. Внешний диапазон "один выстрел". Он срабатывает сразу из-за /^/, который соответствует любой строке, затем он остается активным до последней строки ($). Внутренний диапазон является диапазоном переключения. Он также запускается сразу же, потому что // вызывает /^/ в этой строке (и только в этой строке, следовательно, в одном диапазоне), затем он остается активированным для 3 дополнительных строк (конечный адрес +3 является GNU расширение). После этого /^/ больше не оценивается, поэтому внутренний диапазон не может сработать снова, потому что // вызывает /^this:/ (что является ранним сокращением).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...