【问题标题】:Combining and summing data from multiple files合并和汇总来自多个文件的数据
【发布时间】:2012-08-01 14:34:59
【问题描述】:

我有 2 个如下所示的文件:

文件1

aaa 5
bbb 2
ccc 9
ddd 46
eee 89
fff 56

文件 2

aaa 54
bbb 8
ccc 16
ddd 4
eee 66
fff 9

我想要特定列的总和 (例如两个文件中 aaa 的总和 和 ccc 的总和 + ddd 的总和 和 bbb 的总和 + eee 的总和 + fff 的总和)

例如,有没有一种简单的方法可以使用 awk 做到这一点?

【问题讨论】:

  • 请显示给定输入所需的输出。
  • 是的,awk 是要走的路。这是一个简单的练习,因此请查看一些示例。
  • 将所需的输出添加为问题的编辑可能比作为评论更好。

标签: linux shell


【解决方案1】:

如果你只是想要总和,这可以在纯 bash 中完成(这里使用关联数组,因此需要 bash 4):

declare -A sums
while read name val1 val2; do
  sums[$name]=$(( val1 + val2 ))
done < <(join -j 1 file1 file2)

echo "Sum of aaa: ${sums[aaa]}"
echo "Sums of ccc and ddd: $(( ${sums[ccc]} + ${sums[ddd]} ))"
echo "Sums of bbb, eee, and fff: $(( ${sums[bbb]} + ${sums[eee]} + ${sums[fff]} ))"

【讨论】:

  • 实际上这也很好用,查尔斯,谢谢!我没有试过,因为我先看到了肯特的回复..
【解决方案2】:

aaa 总和示例:

kent$  awk 'NR==FNR{a[$1]=$2;next;}{a[$1]+=$2}END{print "sum of aaa:",a["aaa"]}' file1 file2
sum of aaa: 59

您可以更改END{xxx} 部分以获得不同类型的“总和” :) 例如a["bbb"]+a["eee"]会给你bbb+eee的总和

【讨论】:

  • 谢谢肯特!工作正常,对不起查尔斯,我没有看到我的评论被删掉了,是的,最好把它放在问题中,我的错,我是新来的
  • 不需要NR==FNR 命令。只需删除该模式/动作对。如果数组条目不存在,+= 等效于 =
【解决方案3】:

连接成一个文件并使用:

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

您可以通过管道将输出从 cat 传输到 awk:

cat file1 file2 | awk '...

如果要对输出进行排序,请将其通过管道排序。

【讨论】:

    【解决方案4】:

    我也在做同样的事情,但由于我有很大的文件,我不认为使用 awk 数组连接和求和是一个好主意。

    我实际上正在使用这个:

    join -t$'\t' --check-order -a 1 -a 2 -e 0 -1 1 -2 1 file1 file2 > joined.tmp
    awk 'BEGIN{FS="\t"; OFS="\t"}{print $1, $2+$3}' joined.tmp > merged.txt
    

    我一直在寻找一种更快的方法,但我认为对于大文件,此解决方案比之前的答案中提出的解决方案要好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-31
      • 2021-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-01
      • 2016-06-08
      • 1970-01-01
      相关资源
      最近更新 更多