汇总数据列(单个数字)

时间:2014-05-22 11:59:20

标签: linux bash gnu-coreutils

我正在寻找一种快速添加数据行的方法,例如

3333456332....
3334456332....
3343446332....
3331355332....

(但更长)并将每个数字加到此结果中:

12 12 13 11 15 19 22 12 12 4

这是否可以使用单线程?还是更复杂?

3 个答案:

答案 0 :(得分:3)

awk的好几点:

awk -v FS="" '{for(i=1; i<=NF; ++i) a[i]+=$i} END {for (i=1; i<=NF; ++i) printf "%d ", a[i] }' file

这会创建一个数组a,它会累积每个数字的所有总和。在文件的END处,浏览数组并打印所有总和。

FS变量在这里很重要,因为这意味着该行上的每个数字都被视为一个单独的字段。

输出:

12 12 13 11 15 19 23 12 12 8

更新

以上代码不会在总和之后打印换行符,这可能是您想要的。正如fedorqui的评论中所建议的那样,可以采取一种方式:

awk -v FS="" '{for (i=1; i<=NF; ++i) a[i]+=$i} END {for (i=1; i<=NF; ++i) printf "%d%s", a[i], (i<NF?" ":"\n") }' file

在所有值之间打印一个空格,然后在最后打印一个换行符。

或者,如果你喜欢连接字符串,你可以这样做:

awk -v FS="" '{for(i=1; i<=NF; ++i) a[i]+=$i} END{for (i=1; i<=NF; ++i) s=s a[i] " "; print s}' file

首先构建字符串s,然后构建printprint默认为您添加换行符。


choroba's answer的启发,这是使用Perl的替代版本:

perl -F'' -wane 'pop @F; $i=0; $s[$i++]+=$_ for @F }{ print "@s\n"' file

与在awk中一样,将字段分隔符设置为''。使用“autosplit”开关-a创建数组@F,每个元素包含一位数。

@F的最后一个元素是换行符"\n",因此pop将其删除。数组@s保留所有总和。-n开关意味着整个命令被while (<>) { ... }包围,因此使用}{“eskimo运算符”有效地创建了一个END阻止。 通过将特殊变量$"设置为空格 $"默认为空格,因此可以一次打印数组,每个元素用空格分隔。 / p>

答案 1 :(得分:2)

这是我的版本

grep -o . | pr -4 -t | sed -r 's/\s+/+/g' | bc | xargs

答案 2 :(得分:0)

Perl解决方案:

perl -ne 'chomp; 1 == $. ? @s : @F = split //; $_ += shift @F for @s  }{ print "@s\n"'