次の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 の場合比較して印刷します。利点は、;
フィールド区切り記号を使用してこのソリューションでフィールド番号付けの問題が発生しないことです。
一般に、,
可能であれば、小数点区切り文字を使用しないことをお勧めします。もちろん、これはデータを提供する人によって異なります。
答え2
@Ed Mortonと@steeldriverのコメントを回答に追加するには、GNU awkにコンマを小数点区切り文字として扱い、有効にするか、--posix
/--use-lc-numeric
定義されたロケールを使用させることができます-N
。
たとえば、
$ LC_NUMERIC=fi_FI.UTF-8 awk -N '$1 > 1000' data.txt
1001,055
または:
$ LC_NUMERIC=fi_FI.UTF-8 awk --posix '$1 > 1000' data.txt
1001,055
点を小数点区切り文字として扱う限り、そのようなものは数字756,75788
として認識されず、文字列として認識され、比較は文字列ベースです。7
後の並べ替え1
と,
前の並べ替え0
、したがって756,75788
>1000
と1,151
<です1000
。 (ロケールの照合規則も使用しているかどうかはわかりませんが、,
解釈方法に影響を与える可能性があります。)
($1 + 0)
以下を使用して、値を数値として扱うように強制できます。これは質問のデータで機能するようですが、たとえば印刷1000,1
され1000
ません。 「1000より大きい」ではなく「最小1000」を確認するには、小数($1 + 0) >= 1000
部を使用して無視してください。
望むより:6.1.4.2 ロケール環境が変換に影響を与えるそして6.3.2.1 文字列型と数値型GNU awk マニュアルにあります。(後のページの例は、37
<42
比較がテキストなのか数値なのかは重要ではないため、愚かなものです。)