根据csv中的列条件计算awk的平均值

根据csv中的列条件计算awk的平均值

我有以下csv格式。有整个月的瓦尔,但我把它分成了块

2415.02,2203.35,00:17,25:May:2017,
3465.02,2203.35,01:17,25:May:2017,
2465.02,2203.35,12:17,26:May:2017,
465.02,2203.35,13:17,26:May:2017,
245.02,2203.35,14:17,26:May:2017,
2465.02,2203.35,05:17,26:May:2017,
2865.02,2203.35,06:17,27:May:2017,
2490.12,2203.35,07:17,27:May:2017,

我需要根据当天的值(4 美元)计算第一列的平均值(1 美元)。请注意,如果需要更容易计算,我可以重新格式化日期。

我的悲惨尝试是这样的:

$ awk  '{FS=","; day=$4;value+=$1} END{ print  day,value/NR}' file
27:May:2017 2109.41

我需要这样的输出:

Average for 25th May is *average_for_25th_day*
Average for 27th May is *average_for_26th_day*
Average for 28th May is *average_for_27th_day*

答案1

看一下这个:

awk -F, '{date1[$4]+=$1;++date2[$4]}END{for (key in date1) print "Average of",key,"is",date1[key]/date2[key]}' file
Average of 27:May:2017 is 2677.57
Average of 26:May:2017 is 1410.02
Average of 25:May:2017 is 2940.02

解释:

-F,:定义分隔符。或者可以是awk 'BEGIN{FS=","}...

然后我们创建两个数组date1date2其中我们使用第四个字段$4作为数组索引/键,使用第一个字段$1作为添加到同一数组位置的现有值的值。

所以对于第一行我们会有

date1[27:May:2017]+=2415.02
++date2[27:May:2017]--> 将值增加 1 --> 第一行的值 1

对于下一个相同的日期(第 2 行),我们将有

date1[27:May:2017]+=2415.02 + 3465.02
++date2[27:May:2017]--> 将值增加 1 --> 值 2(第二行)

相同的逻辑扩展到具有相同日期的所有行以及所有不同的日期。

最后,我们使用循环for来迭代数组的键date1(或者date2- 两个数组中的键相同 => $4),对于每个key找到的值,我们打印key(=日期 $4) 并且我们还打印date1[key]值 = 的总和$1同一日期的所有值$4除以date2[key]值 = 找到的具有相同日期的行的数字计数 = 相同$4

答案2

这是一个变体,使用GNU 数据混合进行平均:

datamash -t, groupby 4 mean 1 < file | 
  awk -F'[,:]' '{printf "Average for %dth %s is %f\n", $1,$2,$4}'
Average for 25th May is 2940.020000
Average for 26th May is 1410.020000
Average for 27th May is 2677.570000

相关内容