Bash命令对一列数字求和

Bash command to sum a column of numbers

本问题已经有最佳答案,请猛点这里访问。

我需要一个bash命令,我可以通过管道输入该命令,它将对一列数字求和。我只想要一个快速的一行程序,可以做一些基本上类似的事情:

1
cat FileWithColumnOfNumbers.txt | sum


使用现有文件:

1
paste -sd+ infile | bc

使用STDIN:

1
<cmd> | paste -sd+ | bc

编辑:对于一些粘贴实现,从stdin读取时需要更加明确:

| paste -sd+ - | bc


我喜欢选择的答案。然而,它往往比awk慢,因为这项工作需要两个工具。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ 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


两行数吗?

1
2
awk '{ sum += $1; }
     END { print sum; }'
"$@"

然后你就可以不用多余的"猫"了:

1
2
sum < FileWithColumnOfNumbers.txt
sum   FileWithColumnOfNumbers.txt

fwiw:在MacOS X上,你可以用一个一行程序:

1
awk '{ sum += $1; } END { print sum; }'"$@"


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

1
awk '{s+=$1} END {print s}' filename

[Ghostdog74s评论的后续报道]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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


您可以使用BC(计算器)。假设您的文件名为"n":

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

tr将所有换行改为"+",然后在最后一个加号后附加0,然后将表达式(1+2+3+0传送到计算器。

或者,如果您可以使用awk或perl,这里有一个perl一行程序:

1
2
$perl -nle '$sum += $_ } END { print $sum' n
6


1
while read -r num; do ((sum += num)); done < inputfile; echo $sum


如果安装了Ruby

1
cat FileWithColumnOfNumbers.txt | xargs ruby -e"puts ARGV.map(&:to_i).inject(&:+)"

使用for循环迭代您的文件…

1
sum=0; for x in `cat <your-file>`; do let sum+=x; done; echo $sum


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