Bash command to sum a column of numbers

Bash

Bash Problem Overview


I want a bash command that I can pipe into that will sum a column of numbers. I just want a quick one liner that will do something essentially like this:

cat FileWithColumnOfNumbers.txt | sum

Bash Solutions


Solution 1 - Bash

Using existing file:

paste -sd+ infile | bc

Using stdin:

<cmd> | paste -sd+ | bc

Edit: With some paste implementations you need to be more explicit when reading from stdin:

<cmd> | paste -sd+ - | bc

Options used:

> -s (serial) - merges all the lines into a single line > > > -d - use a non-default delimiter (the character + in this case)

Solution 2 - Bash

I like the chosen answer. However, it tends to be slower than awk since 2 tools are needed to do the job.

$ 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

Solution 3 - Bash

The following command will add all the lines(first field of the awk output)

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

Solution 4 - Bash

Does two lines count?

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

You can then use it without the superfluous 'cat':

sum < FileWithColumnOfNumbers.txt
sum   FileWithColumnOfNumbers.txt

FWIW: on MacOS X, you can do it with a one-liner:

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

Solution 5 - Bash

[a followup to ghostdog74s comments]

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

Solution 6 - Bash

You can use bc (calculator). Assuming your file with #s is called "n":

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

The tr changes all newlines to "+"; then we append 0 after the last plus, then we pipe the expression (1+2+3+0) to the calculator

Or, if you are OK with using awk or perl, here's a Perl one-liner:

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

Solution 7 - Bash

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

Solution 8 - Bash

Use a for loop to iterate over your file …

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

Solution 9 - Bash

If you have ruby installed

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

Solution 10 - Bash

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJubalView Question on Stackoverflow
Solution 1 - BashDimitre RadoulovView Answer on Stackoverflow
Solution 2 - Bashghostdog74View Answer on Stackoverflow
Solution 3 - Bashminhas23View Answer on Stackoverflow
Solution 4 - BashJonathan LefflerView Answer on Stackoverflow
Solution 5 - BashDimitre RadoulovView Answer on Stackoverflow
Solution 6 - BashDVKView Answer on Stackoverflow
Solution 7 - BashDennis WilliamsonView Answer on Stackoverflow
Solution 8 - Basht6dView Answer on Stackoverflow
Solution 9 - BashJoe CannattiView Answer on Stackoverflow
Solution 10 - BashpacoView Answer on Stackoverflow