gawk со сложным разделителем записей печатает только первую запись совпадения

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

 $ gawk 'BEGIN{RS="{Mon,Tue} Mar {21,22} [0-9]{2}:[0-9]{2}:[0-9]{2} 2016";FS ="\n";OFS="\n"} {print savedRT, $1, $2, $3, $4} {savedRT = RT}' iostat.20160321

Mon Mar 21 20:05:00 2016
 cpu
us sy wt id
4  2  0 94

Вот шаблон форматирования входных данных:

Mon Mar 21 20:05:00 2016
 cpu
us sy wt id
4  2  0 94
...
...
...
Mon Mar 21 20:10:00 2016
 cpu
us sy wt id
3  2  0 94
...
...
...

Есть ли глобальный флаг с gawk? Что мне не хватает?


person user3155618    schedule 05.05.2016    source источник
comment
Этот разделитель записей выглядит подозрительно. Что ты там пытаешься делать?   -  person Benjamin W.    schedule 05.05.2016
comment
Я пытаюсь сопоставить строку, содержащую дату и время. Кажется, работает, но только для первой записи.   -  person user3155618    schedule 05.05.2016
comment
{Mon,Tue} не является чередованием в регулярном выражении. Я думаю, что ваш RS никогда не сопоставляется, весь файл рассматривается как одна запись, и вы просто распечатываете его первые четыре поля (есть также пустая строка, где печатается savedRT, но это пустая строка).   -  person Benjamin W.    schedule 05.05.2016
comment
Хорошо, в этом есть смысл. Любые предложения по правильному выражению регулярного выражения?   -  person user3155618    schedule 05.05.2016


Ответы (1)


Вы можете исправить это следующим образом (требуется GNU awk 1):

$ awk 'BEGIN {
    RS = "(Mon|Tue) Mar (21|22) [0-9]{2}:[0-9]{2}:[0-9]{2} 2016"
    FS = OFS = "\n"
}
NR > 1 { print savedRT $1, $2, $3, $4 }
{ savedRT = RT }' infile
Mon Mar 21 20:05:00 2016
 cpu
us sy wt id
4  2  0 94
Mon Mar 21 20:10:00 2016
 cpu
us sy wt id
3  2  0 94

Потребовались следующие изменения:

  • Измените {Mon,Tue} и {21,22} в разделителе записей на (Mon|Tue) и (21|22) для правильного чередования регулярных выражений
  • Начинайте печать, только если NR больше 1; файл начинается с разделителя записей, поэтому первая запись пуста, и мы не хотим печатать кучу пустых строк.
  • savedRT содержит новую строку, поэтому, если мы напечатаем ее как print savedRT, $1, будет слишком много новой строки. Изменение на print savedRT $1 удаляет лишнюю новую строку.

1 Чтобы быть точным, GNU awk 4.0.0 или новее, поскольку выражения интервала [0-9]{2} не распознаются старыми gawk, см. примечания к выпуску. Обходной путь - просто использовать вместо этого [0-9][0-9].

person Benjamin W.    schedule 05.05.2016
comment
Спасибо за вашу помощь. Я попробовал это и не получил результата. Я заменил gawk на awk в ответе, поскольку awk не поддерживает регулярные выражения для разделителей записей. - person user3155618; 05.05.2016
comment
Исправлено сейчас. Проблема заключалась в {2} в регулярном выражении, оно должно быть [0-9] [0-9] вместо [0-9] {2}. Я отредактировал ответ, и он ожидает экспертной оценки. Большое спасибо за помощь. - person user3155618; 05.05.2016
comment
@ user3155618 Он работает точно так же, как и на моем awk (GNU awk 4.0.1). Я уже упоминал, что для этого требуется GNU awk; который awk вызывается при использовании awk, зависит от системы. - person Benjamin W.; 05.05.2016
comment
@ user3155618 FWIW Я принял правку и изменил ее, чтобы указать, что требуется GNU awk, однако она собиралась отклонить. Регулярное выражение изменять не нужно. - person Benjamin W.; 05.05.2016
comment
Спасибо за объяснение. Я использую GNU Awk 3.1.7, который не должен правильно обрабатывать [0-9] {2}. - person user3155618; 05.05.2016
comment
@ user3155618 Фактически это было введено только в gawk 4.0.0, я добавил для этого примечание. - person Benjamin W.; 05.05.2016