В sed или awk, как мне обрабатывать разделители записей, которые * могут * занимать несколько строк? - PullRequest
3 голосов
/ 22 ноября 2008

Мой файл журнала:

 Wed Nov 12 blah blah blah blah cat1
 Wed Nov 12 blah blah blah blah
 Wed Nov 12 blah blah blah blah 
 Wed Nov 12 blah blah blah blah cat2
     more blah blah
     even more blah blah
 Wed Nov 12 blah blah blah blah cat3
 Wed Nov 12 blah blah blah blah cat4

Я хочу разобрать полные многострочные записи, где cat находится в первой строке. Какой лучший способ сделать это в sed и / или awk?

т.е. я хочу, чтобы мой синтаксический анализ дал:

 Wed Nov 12 blah blah blah blah cat1
 Wed Nov 12 blah blah blah blah cat2
     more blah blah
     even more blah blah
 Wed Nov 12 blah blah blah blah cat3
 Wed Nov 12 blah blah blah blah cat4

Ответы [ 4 ]

1 голос
/ 22 ноября 2008

, если вы говорите, что каждая строка, начинающаяся с пробела, является продолжением следующего за ним простого (g) awk (это из моей памяти, так что, возможно, оно содержит некоторые незначительные опечатки и для лучшей читаемости с некоторыми дополнительными переносами строк):

awk " BEGIN { multiline = 0;} 
      ! /^ / { if (whatever) 
                 { print; multiline = 1;} 
               else 
                 multiline = 0; 
             } 
        /^ / {if (multiline == 1) 
                 print;
             } 
     " 
      yourfile

, где whatever - это ваша проверка, должен ли ваш вывод произойти (например, для кошки).

1 голос
/ 22 ноября 2008

Если ваш файл журнала не содержит управляющих символов '\01' и '\02' и что непрерывная строка начинается ровно с четырех пробелов, может сработать следующее:

c1=`echo -en '\01'`
c2=`echo -en '\02'`
cat logfile | tr '\n' $c1 | sed "s/$c1    /$c2/g" | sed "s/$c1/\n/g" | grep cat | sed "s/$c2/\n    /g"

Объяснение: при этом каждая новая строка заменяется на ASCII 1 (управляющий символ, который никогда не должен появляться в файле журнала), а каждая последовательность "newline-space-space-space-space" - на ASCII 2 (другой управляющий символ). Затем он заменяет ASCII 1 на новые строки, поэтому теперь каждая последовательность из нескольких строк помещается в одну строку, а старые разрывы строк заменяются на ASCII 2. Это заменяется на cat, а затем ASCII 2 заменяются на Комбинация newline-space-space-space-space.

0 голосов
/ 18 апреля 2014

Другим подходом было бы установить RS как нечто отличное от нормального \n. Например:

$ awk -v Pre=Wed 'BEGIN {RS = "\\n?\\s*" Pre} /cat.\n?/ {print Pre $0}' file.log
Wed Nov 12 blah blah blah blah cat1
Wed Nov 12 blah blah blah blah cat2
     more blah blah
     even more blah blah
Wed Nov 12 blah blah blah blah cat3
Wed Nov 12 blah blah blah blah cat4
0 голосов
/ 22 ноября 2008

Как то так?

awk 'function print_part() { if(cat) print part }  /^  / { part = part "\n" $0; next } /cat[0-9]$/ { print_part(); part = $0; cat = 1; next;  } { print_part(); cat=0} END { print_part() }' inputfile

Регулярное выражение /^ / определяет строки продолжения.

Регулярное выражение /cat[0-9]$/ определяет начальные строки, которые вы хотите сохранить.

...