如何通过使用bash命令来对一列数据求和?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (10)
  • 关注 (0)
  • 查看 (52)

我想要的是可以对一列数字进行求和的bash命令:

cat FileWithColumnOfNumbers.txt | sum
提问于
用户回答回答于

使用现有文件:

paste -sd+ infile | bc

使用stdin:

<cmd> | paste -sd+ | bc

当需要实现粘贴的时候,你可以从stdin中读取:

<cmd> | paste -sd+ - | bc

用户回答回答于
[root@pentest3r ~]# (find / -xdev -size +1024M) | (while read a ; do aa=$(du -sh $a | cut -d "." -f1 ); o=$(( $o+$aa )); done; echo "$o";)
用户回答回答于

如果你安装了ruby的话,可以使用以下代码:

cat FileWithColumnOfNumbers.txt | xargs ruby -e "puts ARGV.map(&:to_i).inject(&:+)"
用户回答回答于

使用for循环来迭代文件:

sum=0; for x in `cat <your-file>`; do let sum+=x; done; echo $sum
用户回答回答于
while read -r num; do ((sum += num)); done < inputfile; echo $sum
用户回答回答于

假设你的#s文件被称为“n”的话,你可以使用bc(计算器):

$ cat n
1
2
3
$ (cat n | tr "\012" "+" ; echo "0") | bc 
6

tr将所有换行符更改为“+”;并且在最后一个加号后加上0,最后将表达式(1+2+3+0)追加到计算器

如果你使用awk和perl也没有问题的话,你可以使用以下代码:

$perl -nle '$sum += $_ } END { print $sum' n
6
用户回答回答于
bash-2.03$ uname -sr
SunOS 5.8

bash-2.03$ perl -le 'print for 1..49999998' > infile

bash-2.03$ wc -l infile
 49999998 infile

bash-2.03$  time paste -sd+ infile | bc
bundling space exceeded on line 1, teletype
Broken Pipe

real    0m0.062s
user    0m0.010s
sys     0m0.010s

bash-2.03$ time nawk '{s+=$1}END{print s}' infile
1249999925000001

real    2m0.042s
user    1m59.220s
sys     0m0.590s
bash-2.03$ time /usr/xpg4/bin/awk '{s+=$1}END{print s}' infile
1249999925000001

real    2m27.260s
user    2m26.230s
sys     0m0.660s

bash-2.03$ time perl -nle'
  $s += $_; END { print $s }
   ' infile
1.249999925e+15

real    1m34.663s
user    1m33.710s
sys     0m0.650s
用户回答回答于

以下命令将添加所有行(awk输出的第一个字段)

awk '{s+=$1} END {print s}' filename
用户回答回答于
awk '{ sum += $1; }
     END { print sum; }' "$@"

通过以下代码可以不使用多余的cat:

sum < FileWithColumnOfNumbers.txt
sum   FileWithColumnOfNumbers.txt

FWIW:在MacOSX上,你可以使用以下代码来完成它:

awk '{ sum += $1; } END { print sum; }' "$@"
用户回答回答于
$ wc -l file
49999998 file

$ time paste -sd+ file | bc
1448700364

real    1m36.960s
user    1m24.515s
sys     0m1.772s

$ time awk '{s+=$1}END{print s}' file
1448700364

real    0m45.476s
user    0m40.756s
sys     0m0.287s

扫码关注云+社区