【问题标题】:sum column based on two matching fields using awk使用 awk 基于两个匹配字段的求和列
【发布时间】:2011-08-07 17:25:28
【问题描述】:

我似乎找不到这个简单任务的 awk 解决方案。我可以根据一个匹配字段 ($1) 轻松地对一列 ($3) 求和:

awk -F, '{array[$1]+=$3} END { for (i in array) {print i"," array[i]}}' datas.csv

现在,我如何根据两个字段来做到这一点?让我们说 $1 和 $2 ?这是一个示例数据:

P1,gram,10  
P1,tree,12  
P1,gram,34  
P2,gram,23  
...

如果第一个和第二个字段匹配,我只需对第 3 列求和。

感谢您的帮助!

【问题讨论】:

    标签: awk


    【解决方案1】:

    像这样

    awk -F, '{array[$1","$2]+=$3} END { for (i in array) {print i"," array[i]}}' datas.csv
    

    我的结果

    P1,tree,12
    P1,gram,44
    P2,gram,23
    

    编辑

    由于 OP 需要逗号保留在输出中,我使用@yi_H 的“逗号修复”编辑了上面的答案。

    【讨论】:

    • 感谢您对 Ray Toal 的回答,但我已经尝试过此解决方案,但它不能满足我的需要,实际上我确实需要将我的字段分开以进行进一步处理...
    • @yi_H 的修复保留了三列输出;答案已编辑。
    • 一个大文件需要大量内存。
    • 很好的观察,@jfgagne。在一个大文件上可以使用sort。 mapreduce 需要数十 GB 的时间。 :)
    【解决方案2】:

    对于需要较少内存但需要先排序的解决方案(没有什么是免费的):

    sort datas.csv | awk -F "," 'NR==1{last=$1 "," $2; sum=0;}{if (last != $1 "," $2) {print last "," sum; last=$1 "," $2; sum=0;} sum += $3;}END{print last "," sum;}'
    

    【讨论】:

      猜你喜欢
      • 2014-08-21
      • 2017-08-19
      • 1970-01-01
      • 2016-12-09
      • 1970-01-01
      • 1970-01-01
      • 2019-06-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多