我有一个像这样的文件
A 1 3 5
B 2 4 7
C 3 5 9
A 9 0 11
C 7 8 0
该文件有88列和100000行。我想总结具有相似第一列的行的所有列,如下所示:
A 10 3 16
B 2 4 7
C 10 13 9
通常我只使用两列:
awk '{a[$1]+=$2;b[$1]+=$3}END{for(i in a)print i, a[i], b[i]|"sort"}'
但是现在我有88列,我想找到一种更简单的方法来为所有88列添加行而不重复我的awk的第一部分(例如c [$ 1] + = $ 4 ...)
任何人都知道更好/更简单的方法吗?
答案 0 :(得分:1)
使用GNU awk实现真正的多维数组:
$ cat tst.awk
{
for (i=2;i<=NF;i++) {
sum[$1][i] += $i
}
}
END {
for (key in sum) {
printf "%s%s", key, OFS
for (i=2;i<=NF;i++) {
printf "%d%s", sum[key][i], (i<NF?OFS:ORS)
}
}
}
$ awk -f tst.awk file
A 10 3 16
B 2 4 7
C 10 13 9
答案 1 :(得分:1)
如果您的awk版本不支持多维数组:
$ awk '{ idx[$1]++; for (i=1;i<=NF; ++i) { total[$1,i-1] += $i; } } END { for (id in idx) { printf("%s ", id); for(i=1;i<NF;++i) { printf("%d ", total[id,i]); } print "" ; } }' /tmp/sample
A 10 3 16
B 2 4 7
C 10 13 9
答案 2 :(得分:0)
使用二维数组,如下所示:
for (col = 2; col <= NF; col++) {
data[$1, col] += $col;
}
答案 3 :(得分:0)
如果你不坚持使用awk,这是一个Perl解决方案:
perl -lanwe '
$i=0;
$k = shift @F;
$s{$k}[$i++] += $_ for @F;
END { print "$_ @{ $s{$_} }" for sort keys %s }
' input_file > output_file
-l
为print
-n
逐行读取输入行-a
将空格上的每一行拆分为@F数组总和保存在由第一列值键入的哈希表%s中。