Поиск между двумя шаблонами и печать данные от первого шаблона до второго шаблона многократно, исключая несоответствие блокам

Я должен искать определенную строку в обратном порядке и распечатать его.

В ниже примера я хочу искать от шаблона not in order до шаблона number of.

Пример: входной файл содержит:

number of characters a[1] 
reg1 
reg2 
reg3 
info a[1] is not in order

number of characters a[3] 
reg1 
reg2 
reg3 
info a[3] is in order


number of characters a[2] 
reg1 
reg2 
reg3 
info a[2] is not in order

вывод должен быть:

number of characters a[1]
reg1 
reg2 
reg3 
info a[1] is not in order

number of characters a[2] 
reg1 
reg2 
reg3 
info a[2] is not in order
4
задан 23 August 2017 в 02:14

4 ответа

perl -00 -ne 'print if /not in order/' file

-00 опция читает файл абзацами.
Эти -n добавляет неявный цикл по всем абзацам в файле.
Затем распечатайте абзац, если он содержит требуемый текст "не в порядке".

2
ответ дан 23 November 2019 в 11:40

Используя in order с новой строкой как разделитель абзацев мы можем сделать:

awk -v RS='in order\n' '/not/{print $0 "in order"}'

awk текст обработок, разделенный шаблоном в RS (разделитель записей) как записи и каждая операция сделан на записи. Так /not/ тесты, если запись соответствует not, и затем мы печатаем запись ($0) наряду с текстом разделителя, который был удален awk.

Так:

$ mawk -v RS='in order\n' '/not/{print $0 "in order"}' foo
number of characters a[1]
reg1
reg2
reg3
info a[1] is not in order


number of characters a[2]
reg1
reg2
reg3
info a[2] is not in order
4
ответ дан 23 November 2019 в 11:40

Если блоки должны закончиться строкой, которая содержит is in order или is not in order, мы можем удалить вещи между ними...

$ sed '/is not in order/,/is in order/ {/is not in order/n;d}' file
number of characters a[1] 
reg1 
reg2 
reg3 
info a[1] is not in order


number of characters a[2] 
reg1 
reg2 
reg3 
info a[2] is not in order

Примечания:

  • /is not in order/,/is in order/ найдите строки между is not in order и is in order, включительно
  • {some commands} сгруппируйте эти команды
  • /is not in order/n пропустите строку с этим шаблоном от следующей команды
  • d удалите указанные строки

Это могло бы казаться замысловатым, чтобы найти строку и затем найти, что он снова пропускает его, но мы не можем использовать пустую строку вместо этого, или sed будет включать управлять здесь флагом в следующей пустой строке и продолжать идти до следующего is in order, который удалит слишком много.

3
ответ дан 23 November 2019 в 11:40

другой подход:

tac file | awk ' BEGIN {weprint=0 ; rem="not necessary, but for clarity"}
  /is not in order$/ { weprint=1 ;}
  ( weprint == 1)    { print $0  ;   rem="same remark here..."; }
  /^number of/       { weprint=0 ;}
' | tac

который мог быть сокращен в случае необходимости...

Если Вы хотите строку разделителя: измените последнюю строку как

"/^number of/" { print ; weprint=0;}
3
ответ дан 23 November 2019 в 11:40

Другие вопросы по тегам:

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