【问题标题】:Simple aggregation using linux scripting使用 linux 脚本的简单聚合
【发布时间】:2012-11-07 18:58:01
【问题描述】:

假设我有一个包含如下行的文本文件:

foo 10
bar 15
bar 5
foo 30
...

生成以下输出的最简单方法是什么:

foo 40
bar 20

?

【问题讨论】:

  • 这取决于“最简单”的定义,但printf 'foo 40\nbar 20\n'似乎并不无道理。

标签: linux bash awk


【解决方案1】:

这样就可以了:

awk '{arr[$1]+=$2;} END { for (i in arr) print i, arr[i]}'  file

有关更多信息,请阅读 Awk 的关联数组。

【讨论】:

    【解决方案2】:

    使用这个 awk 脚本:

    awk '{sums[$1] += $2} END {for (a in sums) print a, sums[a]}' infile
    

    输出:

    foo 40
    bar 20
    

    Use this awk tutorial on using associative arrays:

    【讨论】:

      【解决方案3】:

      如果你对 perl 感兴趣:

      perl -F -lane '$X{$F[0]}=$X{$F[0]}+$F[1];if(eof){foreach (keys %X){print $_." ".$X{$_}}}' your_file
      

      【讨论】:

        【解决方案4】:

        这是排序的一种方式,GNU sed 和 bc:

        sort infile | 
          sed -r ':a; N; s/([^ ]+) +([^\n]+)\n\1/\1 \2 +/; ta; P; D' |
          sed -r 'h; s/[^ ]+/echo/; s/$/ | bc/e; G; s/([^\n]+)\n([^ ]+).*/\2 \1/'
        

        输出:

        bar 20
        foo 40
        

        第一个 sed 使用相同的键连接相邻行,在数字之间添加 +,第二个将总和传递给 bc。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-01-12
          • 1970-01-01
          • 2022-08-13
          • 1970-01-01
          • 2012-11-24
          • 2017-02-08
          • 1970-01-01
          • 2021-06-02
          相关资源
          最近更新 更多