0

我有一个结构如下所示的文本文件。我想将它们加入一列(算术求和并保存为一列)。

文件结构:

1   4   1   4
2   5   2   5
3   6   3   6

这是我想要得到的:

10
14
18
4

6 回答 6

6

对于大多数目的,我认为最好使用外部程序,例如 AWK 或 Perl(有关 AWK 方法,请参阅 cnicutar 的答案);但如果您愿意,您可以在纯 Bash 中执行此操作,如下所示:

while read -a arr ; do
    i=0
    for field in ${arr[*]} ; do
        (( i += field ))
    done
    echo $i
done < input-file.txt > output-file.txt

或者更简洁——但也更骇人听闻——你可以这样写:

while read ; do
    echo $(( ${REPLY//$'\t'/+} ))
done < input-file.txt > output-file.txt

(后者大致相当于各种其他答案的(也是骇人听闻的)基于 sed 的方法)。

于 2013-09-11T20:04:15.120 回答
4

这个怎么样:

awk '{ x=0; for(i = 1; i <= NF; i++) x += $i; print x }' file
于 2013-09-11T19:57:40.903 回答
3

@cnicutar 提供了一个标准的 awk 解决方案,我只是添加了一个 sed 单线(带 bc)来娱乐:

kent$  cat f
1 4 1 4
2 5 2 5
3 6 3 6

kent$  sed 's/ \+/+/g' f|bc
10
14
18

in sed行\+是为了以防您的列被多个空格分隔。

正如@ruakh 建议的那样, sed 's/[[:space:]]\+/+/g' f|bc更通用和可靠。

于 2013-09-11T20:02:29.870 回答
2

使用 sed 将空格替换为加号,然后bc得到结果:

sed 's/\s\+/+/g' input | bc
于 2013-09-11T20:02:35.917 回答
1

或者(awk 解决方案更好,但也很高兴知道有替代方案:))

sed 's/ /+/g' test.txt | sed -E 's/^(.*)$/echo $((\1))/' | bash
于 2013-09-11T20:00:41.533 回答
1

在 Perl 中也有同样的事情(尽管我确信它可以做得更简洁):

perl -nle '$s=0; $s+=$_ for split; print $s'

哦,按照你的标题要求做(对而不是行求和):

perl -nle '$i=0; $s[$i++]+=$_ for split; END { print "@s" }'

因为…… Perl。

于 2013-09-12T08:00:42.987 回答