Сопоставление строк с отслеживанием состояния grep / awk / sed - PullRequest
1 голос
/ 08 мая 2020

У меня есть файл журнала, который содержит записи, которые могут быть разделены на несколько строк, и я хочу найти все экземпляры этих записей.

Например:

AAA normal line
BBB normal line
XXX important line
 important line continuation 1
 important line continuation 2
BBB normal line
 normal line continuation 1
AAA normal line
XXX important line
 important line continuation 1
 important line continuation 2
 important line continuation 3
AAA normal line

Все записи начать с кода (AAA, BBB, XXX и т. д. c). Строки, начинающиеся с кода XXX, и связанные с ними строки продолжения - это те строки, которые мне интересны. Строки продолжения начинаются с пробела, и может быть любое количество строк продолжения. Строки, следующие за строками продолжения, могут начинаться с любого кода.

Я думаю об этом как о разновидности сопоставления с отслеживанием состояния (хотя это не может быть решено таким образом) ... ie: Мне нужно сопоставление строк шаблон XXX, а затем все сразу следующие строки, начинающиеся с пробела (пока они этого не сделают).

Как я могу использовать grep, sed или awk для этого, отслеживая файл журнала?

Обновление: Пример желаемого результата:

XXX important line
 important line continuation 1
 important line continuation 2
XXX important line
 important line continuation 1
 important line continuation 2
 important line continuation 3

Ответы [ 2 ]

1 голос
/ 09 мая 2020

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

sed '/^XXX/{:a;n;/^ /ba};d' file

Если строка начинается с XXX, напечатайте ее, затем выберите следующую строку.

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

Любая другая строка будет удалена.

NB n обычно печатает текущую строку в пространстве шаблона, а затем заменяет ее следующей строкой. Это нормальный цикл в sed, например, sed '' file просто распечатает файл. Если используется опция -n, неявная печать не выполняется, таким образом:

sed -n '/^XXX/{:a;p;n;/^ /ba}' file

достигают тех же результатов.

Если начало строки может быть табуляцией или любым другим пустое пространство, используйте:

sed '/^XXX/{:a;n;/^\s/ba};d' file
1 голос
/ 09 мая 2020

Это awk должно работать:

awk '/^[^ \t]/{p = ($1 == "XXX")} p' file

XXX important line
 important line continuation 1
 important line continuation 2
XXX important line
 important line continuation 1
 important line continuation 2
 important line continuation 3

Описание команды:

  • /^[^ \t]/: Условие, если строка не начинается с пробела или табуляции
  • {: Запустить блок действий
  • p = ($1 == "XXX"): Установить p на 1, если первый столбец XXX в противном случае установите значение 0.
  • }: Конечный блок
  • p: Если p==1, то напечатайте строку

p будет установлено значение 1, когда мы найдем $1 == XXX, и мы будем продолжать печатать строки, пока p снова не станет 0.

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