Если какая-либо строка, следующая непосредственно за совпадением, должна быть удалена, то ваша sedпрограмма должна будет рассмотреть последовательные совпадения. Другими словами, если вы удаляете строку после совпадения, которое также совпадает, то, вероятно, вам следует удалить также и строку, следующую за этим.
Это реализовано достаточно просто - но вам придется немного оглянуться назад.
printf %s\\n 0 match 2 match match \
5 6 match match match \
10 11 12 match 14 15 |
sed -ne'x;/match/!{g;//!p;}'
0
6
11
12
15
Он работает путем замены мест удержания и шаблонов для каждой прочитанной строки, поэтому последнюю строку можно сравнивать с текущей каждый раз. Поэтому, когда sedчитает строку, она обменивается содержимым своих буферов - и предыдущая строка затем является содержимым буфера редактирования, а текущая строка помещается в удерживающее пространство.
Поэтому sedпроверяет предыдущую строку на соответствие matchи, если она !не найдена , запускаются два выражения в {функции }. sedбудет gперезаписывать пространство удержания, перезаписывая пространство образца - это означает, что текущая строка будет находиться как в пространстве удержания, так и в пространстве образца - и затем будет //проверять его на соответствие его недавно скомпилированному регулярному выражению match- и если это не matchтак является printed.
Это означает, что строка печатается только в том случае, если это не так, а в предыдущей строке нет . Это также исключает любые ненужные замены для последовательностей es.match matchmatch
Если вы хотите версию, которая может отбрасывать произвольное количество строк, встречающихся после a match, потребуется немного больше работы:
printf %s\\n 1 2 3 4 match \
match match 8 \
9 10 11 12 13 \
14 match match \
17 18 19 20 21 |
sed -net -e'/match/{h;n;//h;//!H;G;s/\n/&/5;D;}' -ep
... замените 5 на количество строк (включая совпавшую строку), которые вы хотите удалить ...
1
2
3
4
12
13
14
21