Reputation: 54512
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
Upvotes: 24
Views: 64065
Reputation: 882098
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
Upvotes: 7
Reputation: 141
awk, yes, head and paste.
$ yes "`<file.txt awk '{ sum += $2 } END { print sum }'`" | head -n `<file.txt wc -l` | paste -d ' ' file.txt -
Upvotes: 1
Reputation: 1362
The ugly solution:
awk '{printf "%s ", $0}{system(" awk \047 {sum+=$2}END{print sum} \047 file ")}' file
Upvotes: 1
Reputation: 161874
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
Upvotes: 21
Reputation: 45670
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
Upvotes: 3
Reputation: 455312
Offtopic, but in Perl you can do:
perl -nale '$s+=$F[1];push(@a,$_);END{print $_." $s" for(@a);}' file.txt
Upvotes: 1