4

How can I print unique words, number of their occurrences and the sum of their values in the relevant column using a single array in awk?

I'm using awk like:

awk -F, '{sum[$1]+=$2} END{for (x in sum) print x, sum[x]}' inFile

Can I modify the command above to print the total number of occurrences of unique words as well? Something like the below result for the following sample input:

Result (the order of the printed results doesn't matter):

A 2 25 
B 1 12 
C 3 18

Input:

A,15
C,13
C,4
A,10
B,12
C,1

I can add another array to count them separately but I think there should be another way to print it just using the same array.

Is there any index of the array sum which stores the total words seen?

2

This should do:

awk -F, '{x[$1]["count"]++;x[$1]["sum"]+=$2}END{for(y in x){print y,x[y]["count"],x[y]["sum"]}}' in

Basically you replace the array with a multidimensional array in order to store both the count of the occurences of each unique first field and the sum of their relative second fields.

% cat in
A,15
C,13
C,4
A,10
B,12
C,1
% awk -F, '{x[$1]["count"]++;x[$1]["sum"]+=$2}END{for(y in x){print y,x[y]["count"],x[y]["sum"]}}' in
A 2 25
B 1 12
C 3 18
6

No, there is no such index. Array values don't keep count of how many times they have been incremented. The most natural thing to do here is to use a second array:

$ awk -F, '{sum[$1]+=$2;seen[$1]++} END{for(x in sum) print x,seen[x],sum[x]}' file
A 2 25
B 1 12
C 3 18

You can also use a two dimensional array as shown in Kos's answer but, as you can see, that really doesn't simplify things in any way. Alternatively, you could use some perl magic:

$ perl -F, -lane 'push @{$k{$F[0]}},${$k{$F[0]}}[-1]+$F[1]; 
            END{print "$_ ",$#{$k{$_}}+1," ${$k{$_}}[-1]" for keys(%k)}' file
C 3 18
B 1 12
A 2 25

No, that is not line noise and yes, it uses a single array to print everything.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.