match specific line and print all lines except the following line

У меня есть похожие инструкции, как в теме Print Matching line and nth line from the matched line

Мне нужно найти определенную строку, напечатать ее, затем удалить следующую строку (1-я следующая строка), а затем напечатать остальные до совпадения с определенной строкой и т.д.

Другими словами, мне нужно удалить только строки с , которые следуют за строкой, начинающейся с .

Мой файл:




Bla
bla
bla
.


Bla
bla
bla
.




...

Мой требуемый вывод:



Bla
bla
bla
.


Bla
bla
bla
.



...

-1
07.09.2017, 13:32
3 ответа

С GNUsed:

sed -z -i 's:<doc>\n</s>:<doc>:g' infile.txt

Это заменяет <doc>, за которым следует </s>, только на <doc>. Флаг sed-iиспользуется для замены на месте; а флаг gзаменяет все вхождения . -zзаставляют разделять строки символами NULL.

1
28.01.2020, 05:07

Как вы отметили shell_script, я бы предложилawkподход:

awk '/^<doc>/ && getline nl > 0 && nl!~/^<\/s>/{ print $0 RS nl }1' file

Выход:

<doc>
<s>
Bla
bla
bla
.
</s>
<s>
Bla
bla
bla
.
</s>
</doc>
<doc>
...
0
28.01.2020, 05:07

Это несложно понять, имея базовые sedзнания:

sed '/<doc>/{n;/<\/s>/d;}'

Для строк с <doc>распечатайте его и прочитайте следующую строку с n, а затем, если эта следующая строка содержит </s>(, необходимо экранировать косую черту ), удалите ее с помощью d.

Более подробное объяснение:/expression/{command;command;...;}означает выполнение команд только в строках, соответствующих шаблону, поэтому все остальные строки просто печатаются как есть, а для строки <doc>выполняется n. Эта команда печатает текущую строку и читает следующую, поэтому следующие команды выполняются в следующей строке. Здесь идет другая команда(d)с "адресом" (/<\/s>/), поэтому строка dудаляется, только если она содержит </s>, в противном случае печатается. В любом случае сценарий продолжится со следующей строки.

2
28.01.2020, 05:07

Теги

Похожие вопросы