具有复杂记录分隔符的 gawk 仅打印第一个匹配记录

gawk with complex record separator is only printing the first match record

以下 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, , , , } {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的全局标志吗?我错过了什么?

您可以按如下方式解决此问题(需要 GNU awk1):

$ 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 , , ,  }
{ 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, 那样打印它,就会有一个换行符太多。更改为 print savedRT 会删除多余的换行符。

1 准确地说,GNU awk 4.0.0 或更新版本,因为区间表达式 [0-9]{2} 不能被老 gawks 识别,参见 release notes.解决方法是只使用 [0-9][0-9] 代替。