【发布时间】:2012-11-07 18:58:01
【问题描述】:
假设我有一个包含如下行的文本文件:
foo 10
bar 15
bar 5
foo 30
...
生成以下输出的最简单方法是什么:
foo 40
bar 20
?
【问题讨论】:
-
这取决于“最简单”的定义,但
printf 'foo 40\nbar 20\n'似乎并不无道理。
假设我有一个包含如下行的文本文件:
foo 10
bar 15
bar 5
foo 30
...
生成以下输出的最简单方法是什么:
foo 40
bar 20
?
【问题讨论】:
printf 'foo 40\nbar 20\n'似乎并不无道理。
这样就可以了:
awk '{arr[$1]+=$2;} END { for (i in arr) print i, arr[i]}' file
有关更多信息,请阅读 Awk 的关联数组。
【讨论】:
使用这个 awk 脚本:
awk '{sums[$1] += $2} END {for (a in sums) print a, sums[a]}' infile
输出:
foo 40
bar 20
【讨论】:
如果你对 perl 感兴趣:
perl -F -lane '$X{$F[0]}=$X{$F[0]}+$F[1];if(eof){foreach (keys %X){print $_." ".$X{$_}}}' your_file
【讨论】:
这是排序的一种方式,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。
【讨论】: