Shell command to sum integers, one per line?

2019-01-01 11:53发布

I am looking for a command that will accept as input multiple lines of text, each line containing a single integer, and output the sum of these integers.

As a bit of background, I have a log file which includes timing measurements, so through grepping for the relevant lines, and a bit of sed reformatting I can list all of the timings in that file. I'd like to work out the total however, and my mind has gone blank as to any command I can pipe this intermediate output to in order to do the final sum. I've always used expr in the past, but unless it runs in RPN mode I don't think it's going to cope with this (and even then it would be tricky).

What am I missing? Given that there are probably several ways to achieve this, I will be happy to read (and upvote) any approach that works, even if someone else has already posted a different solution that does the job.

Related question: Shortest command to calculate the sum of a column of output on Unix? (credits @Andrew)


Update: Wow, as expected there are some nice answers here. Looks like I will definitely have to give awk deeper inspection as a command-line tool in general!

标签: shell
30条回答
心情的温度
2楼-- · 2019-01-01 12:10

My version:

seq -5 10 | xargs printf "- - %s" | xargs  | bc
查看更多
浮光初槿花落
3楼-- · 2019-01-01 12:10

Real-time summing to let you monitor progress of some number-crunching task.

$ cat numbers.txt 
1
2
3
4
5
6
7
8
9
10

$ cat numbers.txt | while read new; do total=$(($total + $new)); echo $total; done
1
3
6
10
15
21
28
36
45
55

(There is no need to set $total to zero in this case. Neither you can access $total after the finish.)

查看更多
泪湿衣
4楼-- · 2019-01-01 12:13

I think AWK is what you are looking for:

awk '{sum+=$1}END{print sum}'

You can use this command either by passing the numbers list through the standard input or by passing the file containing the numbers as a parameter.

查看更多
浅入江南
5楼-- · 2019-01-01 12:15

You can do it in python, if you feel comfortable:

Not tested, just typed:

out = open("filename").read();
lines = out.split('\n')
ints = map(int, lines)
s = sum(ints)
print s

Sebastian pointed out a one liner script:

cat filename | python -c"from fileinput import input; print sum(map(int, input()))"
查看更多
怪性笑人.
6楼-- · 2019-01-01 12:16

You can use your preferred 'expr' command you just need to finagle the input a little first:

seq 10 | tr '[\n]' '+' | sed -e 's/+/ + /g' -e's/ + $/\n/' | xargs expr

The process is:

  • "tr" replaces the eoln characters with a + symbol,
  • sed pads the '+' with spaces on each side, and then strips the final + from the line
  • xargs inserts the piped input into the command line for expr to consume.
查看更多
荒废的爱情
7楼-- · 2019-01-01 12:17

Paste typically merges lines of multiple files, but it can also be used to convert individual lines of a file into a single line. The delimiter flag allows you to pass a x+x type equation to bc.

paste -s -d+ infile | bc

Alternatively, when piping from stdin,

<commands> | paste -s -d+ - | bc
查看更多
登录 后发表回答