awk没有与OFMT和$ 0进行四舍五入

时间:2012-10-13 12:27:32

标签: awk gawk

我正在打印一个包含100列的数组,我希望所有列都有2位小数。我想使用print $ 0而不必单独指定所有列的格式。

OFMT看起来与$ 0合作:

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

结果:

0.78
0.78
0.77767686 0.76555555 0.6667667 0.77878878

3 个答案:

答案 0 :(得分:8)

请注意,所有输入都被视为字符串,直到按照它的使用方式进行隐式转换。

当字符串转换为数字时使用

OFMT,例如:

<<< 0.77767686 awk '{ print 0+$0 }' OFMT='%.2g'
数字转换为字符串时使用

CONVFMT,例如:

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

两种情况下的输出:

0.78

后者将$0转换为数字,然后将其与空字符串连接。

要为每个列实现此目的,我建议使用输入和输出记录分隔符的合理设置:

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

请注意两次转换,首先是带有0+$0的数字,然后通过将其与RT连接回字符串。 RT将设置为匹配的记录分隔符。请注意,这是特定于GNU awk的,对于更便携的解决方案,请使用循环,例如:

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

两种情况下的输出:

0.78 0.77 0.67 0.78

答案 1 :(得分:4)

为什么不使用for循环?

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

结果:

0.78
0.77
0.67
0.78

答案 2 :(得分:1)

正如其他人所提到的,您需要将字段视为数字才能获得转化。要结合其他一些想法,您可以尝试:

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

这会将每个字段转换为数字。您只需使用$7 += 0转换单个字段,依此类推。您可以通过if (match($i, ...))使用一些正则表达式来选择仅要转换的数字,从而获得更高的效果。