Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

awk sum a column and print that sum on each line of input

Tags:

bash

printf

sed

awk

My file.txt looks like this:

1 12
2 18
3 45
4 5
5 71
6 96
7 13
8 12

I can sum the second column like this:

awk '{ sum += $2 } END { print sum }' file.txt

272

What's the neatest way that I can print that sum on each line? This is what I'm expecting:

1 12 272
2 18 272
3 45 272
4 5 272
5 71 272
6 96 272
7 13 272
8 12 272
like image 383
Steve Avatar asked May 09 '12 06:05

Steve


4 Answers

Kind of standard awk way.

$ awk 'FNR==NR{sum+=$2;next}; {print $0,sum}' file.txt{,}
1 12 272
2 18 272
3 45 272
4 5 272
5 71 272
6 96 272
7 13 272
8 12 272
like image 73
kev Avatar answered Nov 09 '22 05:11

kev


You can use:

awk -v xyzzy=$(awk '{sum+=$2}END{print sum}' file.txt)
    '{print $0" "xyzzy}' file.txt

This unfortunately means going through the information twice but, since you have to do it once before you get the total, there's no real way around it. Any solution will involve storing up the information before outputting anything (whether in arrays, or going back to the file).

The inner awk works out the total and the outer awk assigns that to a variable which can be printed along with each line.

Applying that to the file:

a 1
b 2
c 3
d 4
e 5

gives you, because 1 + 2 + 3 + 4 + 5 is equal to 15:

a 1 15
b 2 15
c 3 15
d 4 15
e 5 15
like image 38
paxdiablo Avatar answered Nov 09 '22 03:11

paxdiablo


Use arrays

{ 
    a[NR] = $0
    sum += $2
}
END {
    for (x = 1; x <= NR; x++) {
        print a[x], sum
    }
}

Output

$ awk -f s.awk file.txt 
1 12 272
2 18 272
3 45 272
4 5 272
5 71 272
6 96 272
7 13 272
8 12 272

Read more in Gnu Awk Manual

like image 36
Fredrik Pihl Avatar answered Nov 09 '22 04:11

Fredrik Pihl


Offtopic, but in Perl you can do:

perl -nale '$s+=$F[1];push(@a,$_);END{print $_." $s" for(@a);}' file.txt
like image 28
codaddict Avatar answered Nov 09 '22 05:11

codaddict