Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am trying to translate a simple program to the command line using unix utilities. For example, if I have a frequency list (after piping through uniq and sort)

5 x
4 y
1 z

I want to print out, instead of the frequencies, the fraction of the times they occur:

0.5 x
0.4 y
0.1 z

(I have a python program that does this, but I wanted to know if this could be done through the command line itself.)

So far, I have tried to compute the sum

<...>| awk -F" " '{print $1}' | tr '\n' +; echo 0 | bc

but this is just giving me the output 5+1+4+0 without computing it.

EDIT: I got the sum . I modified the above command to

<...>| awk -F" " '{print $1}' | echo $(tr '\n' +; echo 0) | bc > sum 

and the correct result is stored in sum. Now I just want to divide the original list by sum and display it.

share|improve this question
add comment

2 Answers 2

up vote 4 down vote accepted
awk '{ f[$2] = $1; SUM += $1} END { for (i in f) { print f[i]/SUM, i } }' </tmp/data
share|improve this answer
add comment

You can do the summing in awk, and the dividing as well. This will be simpler than invoking bc since you have other data on each line.

This prints the sum of the first field of the input lines:

awk '{sum += $1} END {print $1}'

So you can save the input data, compute the sum, and continue processing the data.

data=$(…)
sum=$(printf '%s\n' "$data" | awk '{sum += $1} END {print $1}')
printf '%s\n' "$data" | awk -v sum="$sum" '{ $1 /= sum; print }'

Or you might make a single pass in awk, retaining all the data in memory.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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