Shortest command to calculate the sum of a column

2019-03-08 02:52发布

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

10条回答
倾城 Initia
2楼-- · 2019-03-08 03:44

Thanks for the Python one-liner above!. It helped me to easy check the used space on my drive. Here is a mixed shell / Python one-liner, that do this - counts used space on the device /dev/sda in megabytes. It took me some time, before I found it out, so, maybe someone finds this useful too.

df -h -B 1M | grep dev/sda | tr -s ' '| cut -d' ' -f3 |python -c "import sys; print sum([int(num) for num in sys.stdin.readlines()])"

or more Python / less shell:

 df -h -B 1M | python -c "import sys; print sum([int(l.split()[2]) for l in sys.stdin.readlines() if '/dev/sda' in l])"

Thanks again!

查看更多
神经病院院长
3楼-- · 2019-03-08 03:48

Python Solution

#!/usr/bin/env python
text= file("the_file","r")
total= 0
for line in text:
    data = line.split()
    if data[0] in ('T', 'Shared', 'IPC'): continue
    print line
    segsize= int(data[6])
    total += segsize
print total

Most Linux distros have Python.

If you want to process stdin as part of a pipline, use

import sys
total = 0
for line in sys.stdin:
   ...etc...

If you want to assume that there's always 3 header lines:

import sys
total = 0
for line in sys.stdin.readlines()[3:]:
    total += int(line.split()[6])
print total

One-liner:

import sys; print sum( [int(line.split()[6]) for line in sys.stdin.splitlines()[3:]] )
查看更多
兄弟一词,经得起流年.
4楼-- · 2019-03-08 03:51

To sum values in a column you can use GNU datamash. Since the first four lines do not contain values you want to sum up, we remove them with tail +4.

ipcs -mb  | tail +4 | datamash -W sum 7

The -W option sets the field delimiter to (possibly multiple) whitespaces.

查看更多
老娘就宠你
5楼-- · 2019-03-08 03:55

I know this question is somewhat dated, but I can't see "my" answer here, so I decided to post nonetheless. I'd go with a combination of

  • tail (to get the lines you need)
  • tr (to shrink down multiple consequitive spaces to one)
  • cut (to get only the needed column)
  • paste (to concatenate each line with a + sign)
  • bc (to do the actual calculation)

ipcs doesn't give an output on my system, so I'll just demo it with df:

# df
Filesystem     1K-blocks    Used Available Use% Mounted on
rootfs          33027952 4037420  27312812  13% /
udev               10240       0     10240   0% /dev
tmpfs             102108     108    102000   1% /run
/dev/xvda1      33027952 4037420  27312812  13% /
tmpfs               5120       0      5120   0% /run/lock
tmpfs             204200       0    204200   0% /run/shm
/dev/xvda1      33027952 4037420  27312812  13% /var/www/clients/client1/web1/log
/dev/xvda1      33027952 4037420  27312812  13% /var/www/clients/client1/web2/log
/dev/xvda1      33027952 4037420  27312812  13% /var/www/clients/client1/web3/log
/dev/xvda1      33027952 4037420  27312812  13% /var/www/clients/client1/web4/log
/dev/xvda1      33027952 4037420  27312812  13% /var/www/clients/client2/web5/log
/dev/xvda1      33027952 4037420  27312812  13% /var/www/clients/client2/web6/log
# df | tail -n +2 | tr -s ' ' | cut -d ' ' -f 2 | paste -s -d+ | bc
264545284

I know doing this particular calculation on my system doesn't really make sense, but it shows the concept.

All of the pieces of this solution have been shown in the other answers, but never in that combination.

查看更多
登录 后发表回答