awk の printf が小数をゼロに置き換えるのはなぜですか?

awk の printf が小数をゼロに置き換えるのはなぜですか?

いくつかの数値が入った単純なファイルがあります:

 2018-11-15 14:07:22      37.672     20.553        15.90   4.0 
 2018-11-17 09:15:46      37.519     20.692        13.80   4.0 
 2018-11-17 20:33:18      37.540     21.712         9.50   4.2 
 2018-11-18 05:18:02      37.391     20.516         0.00   4.3 
 2018-11-18 06:06:44      37.556     20.268         0.00   4.3 
 2018-11-19 05:56:51      37.565     20.678        14.60   4.2 
 2018-11-19 13:05:56      37.179     20.580         6.10   5.1 
 2018-11-19 16:16:41      37.167     20.571         0.10   4.0

3 列目と 4 列目を小数点 1 桁で印刷したいだけです。そのために、次のようにします。

    awk '{printf "%.1f %.1f\n",$3,$4}' myfile

問題は、小数部にゼロが含まれる値が返されることです (この出力は単なる例であり、入力の出力ではありません)。

37,0 20,0
37,0 20,0
40,0 28,0
34,0 26,0
40,0 20,0
34,0 26,0
34,0 26,0
39,0 24,0
37,0 20,0
39,0 24,0
36,0 21,0
37,0 20,0
37,0 20,0
37,0 20,0

何が起こっているのか本当に分かりません...

私のロケールは次のとおりです:

decimal_point=","
thousands_sep="."
grouping=-1;-1
numeric-decimal-point-wc=44
numeric-thousands-sep-wc=46
numeric-codeset="UTF-8"

答え1

コメントで示唆されているように、ロケールではコンマが正しい小数点区切り文字として定義されており、awk ではそれが使用されているようです。

GNU awk ドキュメント標準ではそうすることが要求されていると述べていますが、(ここでのように)、それは多くの場合、より大きな問題であると考えられるため、GNU awk はデフォルトではそうしません。POSIX モードの場合、またはオプションで要求された場合にのみそうします--use-lc-numeric

$ LC_ALL=fi_FI.UTF-8 gawk '{printf "%.1f %.1f\n",$3,$4}' myfile |head -2
37.7 20.6
37.5 20.7

しかし

$ LC_ALL=fi_FI.UTF-8 POSIXLY_CORRECT=1 gawk '{printf "%.1f %.1f\n",$3,$4}' myfile |head -2
37,0 20,0
37,0 20,0

もちろん、awk には異なる慣習がある可能性があり、マニュアルには、GNU awk の古いバージョンもここでの標準に準拠していたことも記載されています。

使用している awk のドキュメントを確認するか、LC_NUMERIC=C実行時にデフォルトのロケールを強制するように設定します。

関連情報