Awk does not round with OFMT and $ 0

I am printing an array with 100 columns, and I would like all the columns to have 2 decimal places. I would like to use print $ 0 and should not individually specify the format for all columns.

OFMT saw work with $ 0:

echo '0.77767686 0.76555555 0.6667667 0.77878878' |awk '{CONVFMT="%.2g";OFMT="%.2g";print ($0+0);print ($0+0)"";print $0}' 

Results:

 0.78 0.78 0.77767686 0.76555555 0.6667667 0.77878878 
+4
source share
3 answers

Note that all input is treated as strings until it is explicitly converted to how it is used.

OFMT used when strings are converted to numbers, for example:

 <<< 0.77767686 awk '{ print 0+$0 }' OFMT='%.2g' 

CONVFMT used when numbers are converted to strings, for example:

 <<< 0.77767686 awk '{ print "" 0+$0 }' CONVFMT='%.2g' 

The conclusion in both cases:

 0.78 

The latter converts $0 to a number and then combines it with an empty string.

To achieve this for each column, I would suggest using a reasonable setting of input and output record separators:

 <<< '0.77767686 0.76555555 0.6667667 0.77878878' \ awk '{ print 0+$0 RT }' CONVFMT='%.2g' RS='[ \t\n]+' ORS='' 

Notice the two conversions, first the number with 0+$0 , then back to the string, combining it with RT . RT will be set to the separator of compatible records. Please note that this is specific to GNU awk; for a more portable solution, use a loop, for example:

 <<< '0.77767686 0.76555555 0.6667667 0.77878878' \ awk '{ for (i=1; i<=NF; i++) $i+=0 } 1' CONVFMT='%.2g' 

The conclusion in both cases:

 0.78 0.77 0.67 0.78 
+8
source

Why don't you use a for loop?

 echo '0.77767686 0.76555555 0.6667667 0.77878878' |awk '{ for (i=1; i<=NF; i++) printf "%.2f\n", $i }' 

Results:

 0.78 0.77 0.67 0.78 
+4
source

As already mentioned, you need to treat the field as a number in order to get the conversion. To combine some other ideas, you can try:

 awk '{ for (i=1; i<=NF; i++) $i += 0; print }' 

This converts each field to a number. You can simply convert individual fields using $7 += 0 and so on. You can get fancier using if (match($i, ...)) with some regex to select only the numbers you want to convert.

+1
source

Source: https://habr.com/ru/post/1439541/


All Articles