2010-10-28 25 views
6

我在文件中有以下几行,我希望按小时计算第三列的平均值。使用awk的列的平均小时数(行)

2010-10-28 12:02:36: 5.1721851 secs 
2010-10-28 12:03:43: 4.4692638 secs 
2010-10-28 12:04:51: 3.3770310 secs 
2010-10-28 12:05:58: 4.6227063 secs 
2010-10-28 12:07:08: 5.1650404 secs 
2010-10-28 12:08:16: 3.2819025 secs 

2010-10-28 13:01:36: 2.1721851 secs 
2010-10-28 13:02:43: 3.4692638 secs 
2010-10-28 13:03:51: 4.3770310 secs 
2010-10-28 13:04:58: 3.6227063 secs 
2010-10-28 13:05:08: 3.1650404 secs 
2010-10-28 13:06:16: 4.2819025 secs 

2010-10-28 14:12:36: 7.1721851 secs 
2010-10-28 14:23:43: 7.4692638 secs 
2010-10-28 14:24:51: 7.3770310 secs 
2010-10-28 14:25:58: 9.6227063 secs 
2010-10-28 14:37:08: 7.1650404 secs 
2010-10-28 14:48:16: 7.2819025 secs 

我已经做了

cat filename | awk '{sum+=$3} END {print "Average = ",sum/NR}' 

与输出

Average = 4.49154 

获得平均为整个文件,但想要小时打破均线向下。我可以在输出awk之前的一个小时内偷偷摸摸一下grep,但是我希望能够用一个班轮来完成。

理想情况下,输出会像

Average 12:00 = _computed_avg_ 
Average 13:00 = _computed_avg_ 
Average 14:00 = _computed_avg_ 

等。

未必寻找答案,但希望能指出正确的方向。

非常感谢!

KM

回答

11

我将字段分隔符设置为冒号,然后聚集在阵列中的不同键的关联数组,并最终计算出的平均值:

gawk -F: 'NF == 4 { sum[$1] += $4; N[$1]++ } 
      END  { for (key in sum) { 
         avg = sum[key]/N[key]; 
         printf "%s %f\n", key, avg; 
        } }' filename | sort 

在您的测试数据,这给:

2010-10-28 12 4.348022 
2010-10-28 13 3.514688 
2010-10-28 14 7.681355 

即使数据不是按时间顺序(例如,您将两个日志文件无序排列),这应该会产生正确的答案。请注意,gawk会以数字方式总结“3.123秒”的值。最后的排序以时间顺序呈现平均值;不能保证按键将按时间顺序打印。

+0

工程就像一个魅力。谢谢乔纳森和诺维科夫。我现在将其逆向工程并试图理解所有不同的部分(尤其是阵列)的作用......( - ;) – 2010-10-29 13:40:56

3

awk有关联数组,所以你可以按小时存储平均值。