awkの浮動小数点比較が期待した結果を生成しないのはなぜですか?

awkの浮動小数点比較が期待した結果を生成しないのはなぜですか?

次のawkスクリプトがあります。

{
    if ($1 > 1000) {
        print $0
    }
}

最初で唯一の列の値が1000を超えるすべての行を印刷する必要があります。

テストデータは次のとおりです。

1,151
1001,055
756,75788

を使用すると、awk -f my_script.awk my_data次の結果が表示されます。

1001,055
756,75788

私が期待するもの:

1001,055

awkのバージョンは次のとおりです。

GNU Awk 5.0.0, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.1.2)

私は何が間違っていましたか?

編集する:

コメントで述べたように:

ここで、カンマは区切り文字ではなく、フランス語で使用される小数点区切り文字で、Wikipediaによると、英語以外のすべての表記システムで使用されています。

編集2:サンプルデータには1列しかありません。実際のデータでは、フィールド区切り文字は「;」です。

ベストアンサー1

婦人声明以下の最初の回避策は、元の問題に対する誤解のために使用されなくなりました。一致する解決策については、編集1と2を参照してください。


awkカンマはデフォルトでは区切り文字として認識されません。タブとスペースに対してのみこれを行います。したがって、区切り文字を明示的に定義する必要があり、そうでない場合はawk文字列値を比較する必要があります。

BEGIN {FS=","}
$1 > 1000

条件が満たされると、1行を印刷する簡単な表記法も使用しています。これは単純なコードのヒントです。

または、コマンドラインで区切り文字を指定します。

awk -F,  -f script.awk infile

編集1以下の仕様は、,小数点区切り文字として使用されます。小数点区切り文字awkとして扱われ、小数点区切り文字を使用するロケールは問題になることがよくあります。.

オプション1の場合は、少しトリックをお勧めします。整数と分数をコンマ区切りの別々のフィールドとして維持し、個別に評価します。

 BEGIN {FS=","}
 $1==1000 && $2>0 || $1 > 1000

その後、a)ロケールの使用をスキップし、b)awk-と-区切りの間を前後に翻訳する試みをスキップします。欠点は、浮動小数点データが多い場合、フィールド番号が列ヘッダーと一致しない可能性があることです。ただし、実際に一致する行だけを印刷する場合は機能しません。,.

このように入力

1,151
1001,055
756,75788
1000
1000,00
1000,000001

戻ってくる

1001,055
1000,000001

編集2別の、おそらくよりエレガントなオプションは、比較のために最初のフィールドをドットで区切られた浮動小数点に変換することです。

gensub(/,/,".","g",$1)+0 > 1000

これは次のように機能します。フィールド 1 を文字列として解釈し、 で置換し,.追加して0-logic で数値にしawk、条件が true の場合比較して印刷します。利点は、;フィールド区切り記号を使用してこのソリューションでフィールド番号付けの問題が発生しないことです。


一般に、,可能であれば、小数点区切り文字を使用しないことをお勧めします。もちろん、これはデータを提供する人によって異なります。

おすすめ記事