AWK-代码未在END规则内按顺序执行

时间:2019-06-24 09:26:21

标签: awk

我正在处理一个文件,创建两个不同的关联数组以计算两个不同模式的频率(即找到的字段3和6)。

文件样本:

2019-06-20 : INFO : XYZ_6789 : [Command [cmd_zip_files]:] Standard output and error
2019-06-20 : INFO : ABC_1234 : License issue
Line with no timestamp
2019-06-20 : INFO : XYZ_6789 : [Command [cmd_zip_files]:] Standard output and error
2019-06-20 : INFO : ABC_1234 : License issue

我想在最后打印两个数组,但是它们的输出重叠。

我正在使用GNU Awk 4.1.3。

我尝试使用“ next / continue”语句,但是它们似乎并不是答案。

也许我以错误的方式使用了END规则。

#!/usr/bin/env awk

BEGIN {
  FS="\\)? : \\(?| \\| |[][]"
  MSG_COL=3
  CMD_COL=6
  SEP="=================="
}

{
  if (match ($MSG_COL, /^[A-Z]{3}_[0-9]+/))
      msg_count[$MSG_COL]++

  if ($MSG_COL == "XYZ_6789")
    cmd_count[$CMD_COL]++
}

END {

  print ">> Count of msg <<"

  for (msg in msg_count)
    if (msg_count[msg] > 0)
      print msg_count[msg], msg | "sort -n"

  print ">> Count of cmd <<"

  for (cmd in cmd_count)
    print cmd_count[cmd], cmd | "sort -n"

}

我希望我的代码提供以下输出:

>> Count of msg <<
2 ABC_1234
2 XYZ_6789
>> Count of cmd <<
2 cmd_zip_files

尽管,我得到了:

>> Count of msg <<
>> Count of cmd <<
2 ABC_1234
2 cmd_zip_files
2 XYZ_6789

2 个答案:

答案 0 :(得分:1)

如果您已经在使用GNU Awk,则应该可以通过设置PROCINFO["sorted_in"]来避免使用subshel​​l和外部实用程序。下面,我使用了@val_num_desc,该数字按降序排列(而不是索引):

awk -F ' : ' '
  /^2019/ {Msg[$3]++; if(split($4, A, "[][]") > 1) Cmd[A[3]]++}
  END {
    PROCINFO["sorted_in"]="@val_num_desc"
    print ">> Count of msg <<"
    for(m in Msg) print Msg[m], m
    print ">> Count of cmd <<"
    for(c in Cmd) print Cmd[c], c
  }
' file
>> Count of msg <<
2 XYZ_6789
2 ABC_1234
>> Count of cmd <<
2 cmd_zip_files

答案 1 :(得分:0)

发生这种情况是因为您自己没有关闭打开的文件句柄。脚本终止时,Awk最终会为您关闭它们,届时将刷新所有暂挂的缓冲输出,但是关闭它们的顺序是不可预测或可靠的。

END块更改为按您想要的顺序显式close

END {
  print ">> Count of msg <<"
  c = "sort -n"
  for (msg in msg_count)
    if (msg_count[msg] > 0)
      print msg_count[msg], msg | c
  close(c)

  print ">> Count of cmd <<"
  c = "sort -n"
  for (cmd in cmd_count)
    print cmd_count[cmd], cmd | c
  close(c)
}