4

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
4

3 に答える 3

10

すべての入力は、使用方法によって暗黙的に変換されるまで、文字列として扱われることに注意してください。

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=''

2 つの変換に注意してください。最初は数値に、0+$0次に で連結して文字列に戻しますRTRT一致したレコード区切りに設定されます。これは 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

編集 - @BeeOnRope への応答

@BeeOnRope は正しく、OFMTprint-function が呼び出されるときにフォーマット指定子として使用されますがsprintf()CONVFMT他の変換では使用されます。違いを示す例を次に示します。

<<< 0.77767686 awk '{ n=0+$1; s=""n; print n, s }' OFMT='%.2g' CONVFMT='%.3g'

出力:

0.78 0.778

GNU awk マニュアルの 2 つの関連セクション:

于 2012-10-15T05:03:33.020 に答える
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
于 2012-10-13T12:34:05.080 に答える
1

他の人が言及したように、変換を取得するにはフィールドを数値として扱う必要があります。他のいくつかのアイデアを組み合わせるには、次のことを試すことができます。

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

これにより、すべてのフィールドが数値に変換されます。個々のフィールドをなどで変換できます$7 += 0。いくつかの正規表現を使用if (match($i, ...))して、変換したい数値のみを選択することで、より洗練されたものになる可能性があります。

于 2012-10-15T06:31:02.510 に答える