4

I am computing the percentages of every item in a column of a file using the following awk command:

awk '{a[NR]=$2;x+=(b[NR]=$2);c[NR]=$1}END{while(++i<=NR)print c[i]"\t"a[i]"\t"100*b[i]/x"%"}' file.txt > out_file.txt

file.txt

N    38668442   
V    14008521   
ADJ  16112215   

out_file.txt

N    38668442   56,213%
V    14008521   20,3644%
ADJ  16112215   23,4226%

However, I would like the percentages in the out_file.txt to be rounded to 2 decimals.

desired out_file.txt

N    38668442   56,21%
V    14008521   20,37%
ADJ  16112215   23,42%

Referring to this post: https://stackoverflow.com/questions/18696096/awk-calculate-sum-of-2nd-column-and-percentage-wrt-sum-and-print

I tried to integrate printf "%s,%d,%0.2f%\n into my code which raises an argument error even by decreasing the arguments and limit the expression to %0.2f%\n.

 awk '{a[NR]=$2;x+=(b[NR]=$2);c[NR]=$1}END{while(++i<=NR)printf "%s,%d,%0.2f%\n",c[i]"\t"a[i]"\t"100*b[i]/x"%"}' file.txt > out_file.txt

Also bc did not work out. Why does it not produce the desired output? In my opinion, it should work as I found the expression printf "%0.2f\n" in several posts concerning the same issue. Do I miss something trivial?

I greatly appreciate any help or suggestions!

7

You are misunderstanding the syntax of the printf command (which closely follows that of the underlying C function: see for example man 3 printf for full documentation).

printf takes a format string consisting of a sequence of format specifiers and other literal characters, followed by as many comma-separated arguments as necessary to fill the given format. In your command

printf "%s,%d,%0.2f%\n",c[i]"\t"a[i]"\t"100*b[i]/x"%"

you are telling it to expect 3 values (a %s, a %d, and a %0.2f) but are giving it a single, concatenated, string argument c[i]"\t"a[i]"\t"100*b[i]/x"%". Hence it will run out of arguments during the assignment.

What you presumably intended is

printf "%s\t%d\t%0.2f%%\n", c[i], a[i], 100*b[i]/x

(the tabs go inside the format string; the %% corresponds to a literal % i.e. prevents % from being interpreted as the start of another format specifier).

  • thank you so much for your explanation and your help! It all makes sense now and I understand it finally! Also, the solution is great and works perfectly as always! I really appreciate your effort! Thank you so much! – dani_anyman Apr 14 '17 at 16:21

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.