awk decimal division

I have a file with values, some are whole numbers & some are with decimals

``````# cat file
value1 100
value2 500.10
value3 2505
value4 35.4
``````

I want to divide each value in field2 with say a fixed number=1000, also sum all values after division. resulting values must carry 5 digits after decimals

``````# cat output.txt
value1 100 0.10000
value2 500.10 0.50010
value3 2505 2.50500
value4 35.4 0.03450
sum   3140.50000 3.14050
``````
• Why must you use `awk`? Is this homework? Apr 17 at 15:06
• @waltinator: what would you use besides awk for this? Apr 17 at 15:09
• Perl, Matlab, a spreadsheet... there are other tools besides awk Apr 17 at 15:48
• You've asked and received answers to several awk questions recently so you must've picked up at least a little about awk - please edit your question to show your attempt to solve the problem yourself. Apr 18 at 11:45
• @roaima my point was there is nothing strange about asking for an awk solution for this. If the CLI is being used awk is the correct tool for the job. If OP had said "without using awk" then it would seem like a homework question. Apr 18 at 12:01

I believe your sum values are off but you could use the following:

``````{
div = \$2 / 1000
sum += \$2
divsum += div
printf "%s %.5f\n", \$0, div
}

END {
printf "sum %.5f %.5f\n", sum, divsum
}
``````

``````\$ awk '{div=\$2/1000;sum+=\$2; divsum+=div; printf "%s %.5f\n", \$0, div}END{printf "sum %.5f %.5f\n", sum, divsum}' file
value1 100 0.10000
value2 500.10 0.50010
value3 2505 2.50500
value4 35.4 0.03540
sum 3140.50000 3.14050
``````

Basically the same idea as @jesse_b's answer, but with one less intermediate variable:

``````\$ awk '{ sum+=\$2; dsum+=\$3=\$2/1000; print} END{print "sum",sum,dsum}' file
value1 100 0.1
value2 500.10 0.5001
value3 2505 2.505
value4 35.4 0.0354
sum 3140.5 3.1405
``````

You can use `printf` if you need more precision:

``````\$ awk '{
sum+=\$2; dsum+=\$3=sprintf("%.5f",\$2/1000); print
}
END{printf "%s%s%.5f%s%.5f\n", "sum",OFS,sum,OFS,dsum}' file
value1 100 0.10000
value2 500.10 0.50010
value3 2505 2.50500
value4 35.4 0.03540
sum 3140.50000 3.14050
``````

And here's a Perl way, for fun:

``````\$ perl -lane '\$sum+=\$F[1]; \$dsum+=\$F[2]=sprintf("%.5f",\$F[1]/1000);
print "@F"; }{ print "sum \$sum \$dsum"' file
value1 100 0.10000
value2 500.10 0.50010
value3 2505 2.50500
value4 35.4 0.03540
sum 3140.5 3.1405
``````

And, with greater precision:

``````\$ perl -lane '\$sum+=\$F[1]; \$dsum+=\$F[2]=sprintf("%.5f",\$F[1]/1000);
print "@F"; }{
printf "sum %.5f %.5f\n", \$sum, \$dsum' file
value1 100 0.10000
value2 500.10 0.50010
value3 2505 2.50500
value4 35.4 0.03540
sum 3140.50000 3.14050
``````
• @αғsнιη sure, OK, I made the perl that way too. And yes, `}{` in Perl is shorthand for `END{}`. You can write `perl 'whatever; END{something}'` or `perl 'whatever; }{ something'`.
– terdon
Apr 17 at 16:00

Here's one way using the GNU desk calculator dc , a command line RpN calculator.

``````sed -E 's/\S+/[&]/' file |
dc -e "
##> final sums displayed
[
[Sum]nlyx
lpd1/nlyx
lzxq
]sq

[
rnlyx
dd lp+sp nlyx
lzx
]sa

[?z0=q lax cz0=?]s?

## > helper macros to pad leading zero for numbers < 1
[0n]s0 [9an]sy
[1000/ddZrX!<0p]sz

##> set precision and start
5kl?x
" - | column -ts\$'\t'
value1  100         0.10000
value2  500.10      0.50010
value3  2505        2.50500
value4  35.4        0.03540
Sum     3140.50000  3.14050
``````