我有一个结构如下所示的文本文件。我想将它们加入一列(算术求和并保存为一列)。
文件结构:
1 4 1 4
2 5 2 5
3 6 3 6
这是我想要得到的:
10
14
18
对于大多数目的,我认为最好使用外部程序,例如 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 的方法)。
这个怎么样:
awk '{ x=0; for(i = 1; i <= NF; i++) x += $i; print x }' file
@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
更通用和可靠。
使用 sed 将空格替换为加号,然后bc
得到结果:
sed 's/\s\+/+/g' input | bc
或者(awk 解决方案更好,但也很高兴知道有替代方案:))
sed 's/ /+/g' test.txt | sed -E 's/^(.*)$/echo $((\1))/' | bash
在 Perl 中也有同样的事情(尽管我确信它可以做得更简洁):
perl -nle '$s=0; $s+=$_ for split; print $s'
哦,按照你的标题要求做(对列而不是行求和):
perl -nle '$i=0; $s[$i++]+=$_ for split; END { print "@s" }'
因为…… Perl。