我正在打印一个包含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
答案 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, ...))
使用一些正则表达式来选择仅要转换的数字,从而获得更高的效果。