根据第一列总结88列

时间:2016-05-17 12:34:40

标签: linux awk

我有一个像这样的文件

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 ...)

任何人都知道更好/更简单的方法吗?

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
  • -lprint
  • 添加换行符
  • -n逐行读取输入行
  • -a将空格上的每一行拆分为@F数组

总和保存在由第一列值键入的哈希表%s中。