5

I have a file that contain numbers something like:

1 11 323
2 13 3
3 44 4
4 66 23
5 70 23
6 34 23
7 24 22
8 27 5

How can I sum the rows and output the results in a column, so the results are as follows:

1 11 323 335
2 13 3 18
3 44 4 51
4 66 23 93
5 70 23 98
6 34 23 63
7 24 22 53
8 27 5 40

I would like to see solutions in sed, awk, and perl

4 Answers4

8

Perl solution:

perl -MList::Util=sum -lane 'print "@F ", sum(@F)' < data.txt
  • -n reads the input line by line
  • -l removes newlines from input and adds them to output
  • -a splits each input line on whitespace into the @F array
  • List::Util provides the sum function so you don't have to sum the numbers yourself

In sed, arithmetic is nearly impossible to implement, but you can use sed to turn spaces into pluses and use that as a source for bc to get the sums, and paste the results with the input:

paste -d ' ' data.txt <(sed -r 's/ /+/g' data.txt | bc)
choroba
  • 45,735
  • 7
  • 84
  • 110
4

Let's say that your data is saved in a file called data.txt.

cat data.txt
1 11 323
2 13 3
3 44 4
4 66 23
5 70 23
6 34 23
7 24 22
8 27 5

You can do it in awk as follows:

awk '{X=$0}{split(X,x)}{print X , x[1]+x[2]+x[3]}' data.txt
1 11 323 335
2 13 3 18
3 44 4 51
4 66 23 93
5 70 23 98
6 34 23 63
7 24 22 53
8 27 5 40

Or, per @RudiC's comment:

awk '{print $0, $1+$2+$3}' data.txt
4

For an arbitrary number of columns, using awk:

$ awk '{ sum = 0; for (i = 1; i <= NF; i++) sum += $i; $(NF + 1) = sum } 1' <file
1 11 323 335
2 13 3 18
3 44 4 51
4 66 23 93
5 70 23 98
6 34 23 63
7 24 22 53
8 27 5 40

NF is the number of fields (whitespace separated columns by default) in the current record (line by default). By calculating sum in a loop and setting $(NF + 1) to the total, we add a new column at the end. This new column is printed along with the others by the lone 1 at the end of the awk script (this may be replaced by { print }).


sed is not really suited for doing any form of arithmetics.

Kusalananda
  • 320,670
  • 36
  • 633
  • 936
  • Thank you! please how can I do it in sed? –  Sep 19 '18 at 15:59
  • 3
    @Shervan You can't. `sed` does not support arithmetic operations. – Kusalananda Sep 19 '18 at 16:00
  • 2
    @Shervan And when I say "you can't", I mean that you can, but it would be _extremely difficult_ as you would have to do so with the aid of regular expressions and the other text manipulating facilities that `sed` provides. It would be as difficult to do with `sed` as with an ordinary plain text editor that does not support arithmetic operations natively. – Kusalananda Sep 19 '18 at 16:04
  • 2
    @Shervan See e.g. my solution to solving a sorting problem with `sed`: https://unix.stackexchange.com/a/436251/116858 – Kusalananda Sep 19 '18 at 16:06
  • 1
    @Kusalananda. he can do something like this `cat data | sed -e 's,$, + p,g' | dc`, no? or `cat data | sed -e 's/\ /+/g' | bc` –  Sep 19 '18 at 16:07
  • 2
    @Goro Yes, that would be using `sed` to generate a `dc`/`bc` script. This is different from doing the actual calculation in `sed` though. – Kusalananda Sep 19 '18 at 16:08
  • 1
    @Kusalananda. of course –  Sep 19 '18 at 16:08
0

What about a pure bash solution ?

while read -r a b c; do
    echo $a $b $c $((a+b+c))
done < input

Sample run

Aaron
  • 281
  • 1
  • 11