【问题标题】:Bash shell using AWK to add up several respective columns / fields?Bash shell 使用 AWK 添加几个相应的列/字段?
【发布时间】:2012-01-22 13:04:32
【问题描述】:

想知道是否有人可以使用 bash shell 脚本和 awk 将多个列/字段相加并打印出摘要。

我想获取以下格式输出的统计数据

REQ_RATE REQ_PROCESSING: 0, REQ_PER_SEC: 1.0, TOT_REQS: 2,
REQ_RATE CACHE_HITS_PER_SEC: 0.5, TOTAL_CACHE_HITS: 10
REQ_RATE REQ_PROCESSING: 0, REQ_PER_SEC: 2.0, TOT_REQS: 0,
REQ_RATE CACHE_HITS_PER_SEC: 0.5, TOTAL_CACHE_HITS: 20
REQ_RATE REQ_PROCESSING: 0, REQ_PER_SEC: 3.0, TOT_REQS: 2,
REQ_RATE CACHE_HITS_PER_SEC: 0.5, TOTAL_CACHE_HITS: 30
REQ_RATE REQ_PROCESSING: 0, REQ_PER_SEC: 4.0, TOT_REQS: 1,
REQ_RATE CACHE_HITS_PER_SEC: 0.5, TOTAL_CACHE_HITS: 40
REQ_RATE REQ_PROCESSING: 0, REQ_PER_SEC: 5.0, TOT_REQS: 0,
REQ_RATE CACHE_HITS_PER_SEC: 0.5, TOTAL_CACHE_HITS: 50

并将它们汇总为一行输出,例如

REQ_RATE REQ_PROCESSING: 0, REQ_PER_SEC: 15.0, TOT_REQS: 5,
REQ_RATE CACHE_HITS_PER_SEC: 2.5, TOTAL_CACHE_HITS: 150

谢谢

【问题讨论】:

  • 您需要 awk 吗?这也可以在 perl 和 python 以及许多其他脚本语言中完成

标签: bash awk


【解决方案1】:

awk 非常好用。

$ awk '/REQ_PROCESSING/{x+=$3; y+=$5; z+=$7}; END{print x, y, z}' input.txt
0 15 5

我想你可以做剩下的。编码愉快!

【讨论】:

  • 感谢 Jaypal 和 kev,您的示例确实帮助我理解了该做什么。看起来kev的示例使用起来更简单,正是我需要的:)
  • 它更简单,但您必须运行两次才能计算所有 5 个统计信息。我的回答是基于你想要的输出。我的代码中可怕的部分是格式。但只要它能让你上路,那就太好了。 :)
【解决方案2】:

这对你有用吗 -

您的文件:

[jaypal:~/Temp] cat file
REQ_RATE REQ_PROCESSING: 0, REQ_PER_SEC: 1.0, TOT_REQS: 2,
REQ_RATE CACHE_HITS_PER_SEC: 0.5, TOTAL_CACHE_HITS: 10
REQ_RATE REQ_PROCESSING: 0, REQ_PER_SEC: 2.0, TOT_REQS: 0,
REQ_RATE CACHE_HITS_PER_SEC: 0.5, TOTAL_CACHE_HITS: 20
REQ_RATE REQ_PROCESSING: 0, REQ_PER_SEC: 3.0, TOT_REQS: 2,
REQ_RATE CACHE_HITS_PER_SEC: 0.5, TOTAL_CACHE_HITS: 30
REQ_RATE REQ_PROCESSING: 0, REQ_PER_SEC: 4.0, TOT_REQS: 1,
REQ_RATE CACHE_HITS_PER_SEC: 0.5, TOTAL_CACHE_HITS: 40
REQ_RATE REQ_PROCESSING: 0, REQ_PER_SEC: 5.0, TOT_REQS: 0,
REQ_RATE CACHE_HITS_PER_SEC: 0.5, TOTAL_CACHE_HITS: 50

测试:

[jaypal:~/Temp] sed '{N;s/\n/ /g'} file |  
awk -F"[:,]" '{a=a+$2;b=b+$4;c=c+$6;d=d+$8;e=e+$10} 
END{printf ("%s: %.1f,%s: %.1f,%s: %.1f,\n%s: %.1f,%s: %.1f\n", $1,a,$3,b,$5,c,$7,d,$9,e)}'
REQ_RATE REQ_PROCESSING: 0.0, REQ_PER_SEC: 15.0, TOT_REQS: 5.0,
REQ_RATE CACHE_HITS_PER_SEC: 2.5, TOTAL_CACHE_HITS: 150.0

【讨论】:

    【解决方案3】:

    如果我们考虑数据的结构,可以得出几个结论:

    • REQ_RATE 不携带任何信息
    • 其余行可以视为键值对
    • 键值对用逗号或换行符分隔

    因此采取两步方法,将行处理成更清晰的键值对:

    sed -e 's/^REQ_RATE //' -e 's/,[[:space:]]*$//' |
      awk -F ', ' -v OFS='\n' '{ $1=$1; print }'
    

    这会生成带有单个键值对的行。

    现在通过另一个 awk 阶段将上述内容通过管道传递,使用关联数组对每个键的值求和:

    awk -F ': ' '
      { 
        sum[$1] += $2 
      } 
      END { 
        for (k in sum) { 
          printf("%s: %d, ", k, sum[k]) 
        } 
        printf("\n")
      }' 
    

    我对输出的格式没有做任何特别的事情,只是以任意顺序的键进行迭代。如果您需要更具体的内容,请修改 END 操作。

    【讨论】:

      猜你喜欢
      • 2012-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-06
      • 2013-05-31
      相关资源
      最近更新 更多