Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shortest command to calculate the sum of a column of output on Unix?

Tags:

shell

unix

math

ksh

I'm sure there is a quick and easy way to calculate the sum of a column of values on Unix systems (using something like awk or xargs perhaps), but writing a shell script to parse the rows line by line is the only thing that comes to mind at the moment.

For example, what's the simplest way to modify the command below to compute and display the total for the SEGSZ column (70300)?

ipcs -mb | head -6 IPC status from /dev/kmem as of Mon Nov 17 08:58:17 2008 T         ID     KEY        MODE        OWNER     GROUP      SEGSZ Shared Memory: m          0 0x411c322e --rw-rw-rw-      root      root        348 m          1 0x4e0c0002 --rw-rw-rw-      root      root      61760 m          2 0x412013f5 --rw-rw-rw-      root      root       8192 
like image 320
An̲̳̳drew Avatar asked Nov 17 '08 15:11

An̲̳̳drew


People also ask

How do you sum a column in Linux?

“UtilityBills. txt” represents the name of the text file from which we have to read the data. Then we have the “awk” keyword followed by the “sum” expression that will actually calculate the sum from the second column of our dataset, and then the “print” command will be used to display the results on the terminal.


2 Answers

ipcs -mb | tail +4 | awk '{ sum += $7 } END { print sum }' 

Or without tail:

ipcs -mb | awk 'NR > 3 { sum += $7 } END { print sum }' 

Using awk with bc to have arbitrary long results (credits to Jouni K.):

ipcs -mb | awk 'NR > 3 { print $7 }' | paste -sd+ | bc 
like image 159
Johannes Schaub - litb Avatar answered Sep 22 '22 05:09

Johannes Schaub - litb


I would try to construct a calculation string and feed it to bc as follows:

  1. grep the lines that contain the numbers
  2. sed away all characters before (and after) the number on each line
  3. xargs the result (to get a string of numbers separated by blanks)
  4. tr anslate the blanks to '+' characters
  5. good appetite bc!

ipcs -mb | grep -w '^m ' | sed 's/^.*\s//' | xargs | tr ' ' + | bc

Looks like this is slightly longer than the awk solution, but for everyone who can't read (and understand) the odd awk code this may be easier to grasp... :-)

If bc is not installed you can use double parentheses in step 5 above to calculate the result:

  • echo $(( $(ipcs -mb | grep -w '^m ' | sed 's/^.*\s//' | xargs | tr ' ' +) )) or
  • SUM=$(( $(ipcs -mb | grep -w '^m ' | sed 's/^.*\s//' | xargs | tr ' ' +) )) or
  • (( SUM=$(ipcs -mb | grep -w '^m ' | sed 's/^.*\s//' | xargs | tr ' ' +) ))

The spacing after and before the double parentheses is optional.

like image 28
Peterino Avatar answered Sep 21 '22 05:09

Peterino