Jacob
Jacob

Reputation: 1671

Sum of tagged lines perl/shellscript

I have input that looks like

5 X
8 Y
3 Z
9 X

I want output that sums the numerical values for each 'tag'; e.g.

14 X
8 Y
3 Z

Wondering if there is a slick one liner I can use (along the lines of the ones for summing a list of integers using awk).

Upvotes: 1

Views: 164

Answers (5)

Vijay
Vijay

Reputation: 67211

gawk "{count[$2]+=$1}END{for(i  in count)print count[i],i}" 1.t

Upvotes: 0

Hynek -Pichi- Vychodil
Hynek -Pichi- Vychodil

Reputation: 26121

Output in random order

perl -alne'$t{$F[1]}+=$F[0]}{print"$t{$_} $_"for keys%t'

alphabetically sorted by tag

perl -alne'$t{$F[1]}+=$F[0]}{print"$t{$_} $_"for sort keys%t'

sorted by value

perl -alne'$t{$F[1]}+=$F[0]}{print"$t{$_} $_"for sort{$t{$b}<=>$t{$a}}keys%t'

Upvotes: 0

Ben
Ben

Reputation:

Tried to make it as little obfuscated as possible :) Sorts output by 'tag'.

perl -alne '$counts{$F[1]} += $F[0]; END { print "$counts{$_} $_" for sort(keys %counts) }'

Upvotes: 0

mob
mob

Reputation: 118595

As slick as I can make it:

perl -alne 'END{print"$X{$_} $_"for sort{$X{$b}<=>$X{$a}}keys%X}$X{$F[1]}+=$F[0]'

Upvotes: 0

Eric Strom
Eric Strom

Reputation: 40142

Something like this should do the trick:

perl -ne '$table{$2} += $1 if /(\d+)\s+(.+)/; END {print "$table{$_} $_\n" for keys %table}'

or to use auto-splitting:

perl -ane '$table{$F[1] or next} += $F[0]; END {print "$table{$_} $_\n" for keys %table}'

Upvotes: 7

Related Questions