当前位置:  开发笔记 > 编程语言 > 正文

如何对日志文件执行计算

如何解决《如何对日志文件执行计算》经验,为你挑选了1个好方法。

我有一个看起来像这样:

I, [2009-03-04T15:03:25.502546 #17925]  INFO -- : [8541, 931, 0, 0]
I, [2009-03-04T15:03:26.094855 #17925]  INFO -- : [8545, 6678, 0, 0]
I, [2009-03-04T15:03:26.353079 #17925]  INFO -- : [5448, 1598, 185, 0]
I, [2009-03-04T15:03:26.360148 #17925]  INFO -- : [8555, 1747, 0, 0]
I, [2009-03-04T15:03:26.367523 #17925]  INFO -- : [7630, 278, 0, 0]
I, [2009-03-04T15:03:26.375845 #17925]  INFO -- : [7640, 286, 0, 0]
I, [2009-03-04T15:03:26.562425 #17925]  INFO -- : [5721, 896, 0, 0]
I, [2009-03-04T15:03:30.951336 #17925]  INFO -- : [8551, 4752, 1587, 1]
I, [2009-03-04T15:03:30.960007 #17925]  INFO -- : [5709, 5295, 0, 0]
I, [2009-03-04T15:03:30.966612 #17925]  INFO -- : [7252, 4928, 0, 0]
I, [2009-03-04T15:03:30.974251 #17925]  INFO -- : [8561, 4883, 1, 0]
I, [2009-03-04T15:03:31.230426 #17925]  INFO -- : [8563, 3866, 250, 0]
I, [2009-03-04T15:03:31.236830 #17925]  INFO -- : [8567, 4122, 0, 0]
I, [2009-03-04T15:03:32.056901 #17925]  INFO -- : [5696, 5902, 526, 1]
I, [2009-03-04T15:03:32.086004 #17925]  INFO -- : [5805, 793, 0, 0]
I, [2009-03-04T15:03:32.110039 #17925]  INFO -- : [5786, 818, 0, 0]
I, [2009-03-04T15:03:32.131433 #17925]  INFO -- : [5777, 840, 0, 0]

我想创建一个shell脚本来计算括号中(8400最后一个示例中)的第2和第3个字段的平均值.一个更棘手的问题是:只有当最后一个字段不是时才能获得第3个字段的平均值0吗?

我知道我可以使用Ruby或使用其他语言来创建脚本,但我想这样做Bash.关于如何创建这样的脚本的资源或提示的任何好建议都会有所帮助.



1> vladr..:

使用bashawk:

cat file | sed -ne 's:^.*INFO.*\[\([0-9, ]*\)\][ \r]*$:\1:p' | awk -F ' *, *' '{ sum2 += $2 ; sum3 += $3 } END { if (NR>0) printf "avg2=%.2f, avg3=%.2f\n", sum2/NR, sum3/NR }'

样本输出(原始数据):

avg2=2859.59, avg3=149.94

当然,您不需要使用cat它,它包含在那里是为了易读性和说明输入数据可以来自任何管道的事实; 如果您必须对现有文件进行操作,请sed -ne '...' file | ...直接运行.


编辑

如果您有权访问gawk(GNU awk),则可以省略sed以下内容:

cat file | gawk '{ if(match($0, /.*INFO.*\[([0-9, ]*)\][ \r]*$/, a)) { cnt++; split(a[1], b, / *, */); sum2+=b[2]; sum3+=b[3] } } END { if (cnt>0) printf "avg2=%.2f, avg3=%.2f\n", sum2/cnt, sum3/cnt }'

同样的评论.cat应用.

一点解释:

sed只打印出-n ... :p与正则表达式匹配的行(组合)(包含INFO的行后跟行尾的方括号之间的数字,空格和逗号的任意组合,允许尾随空格和CR); 如果任何这样的行匹配,只在打印前保持方括号之间的内容(\1对应\(...\)于正则表达式之间的内容:p)

sed将输出如下所示的行: 8541, 931, 0, 0

awk使用逗号包围0或更多空格(-F ' *, *')作为字段分隔符; $1对应于第一列(例如8541),$2第二列等等.缺失列计为值0

最后,awk将累加器sum2等除以处理的记录数,NR

gawk一举一动; 它会先测试每一行是否与前面的例子中传递给同一正则表达式sed(除了不像sed,awk不需要\在弗朗圆括弧划定的区域或利益).如果该行匹配,则圆括号之间的内容最终在[1]中,然后我们使用相同的分隔符(由任意数量的空格包围的逗号)进行拆分并使用它来累积.我介绍cnt而不是继续使用NR因为处理的记录数量NR可能大于相关记录的实际数量(cnt)如果不是所有行都是这种形式INFO ... [...comma-separated-numbers...],但事实并非如此,sed|awk因为sed保证所有行传递给awk 是相关的.

推荐阅读
放ch养奶牛
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有