1行を印刷する必要がありますが、数字を検索するにはawkを使用し、より多くの数字で二重コロンを追加する必要があるシナリオがあります。
以下の例をご覧ください。
test1 test2 37:375003 test3 test4
test1 test2 38:375004 test3 test4
test1 test2 39:375005 test3 test4
test1 test2 40:375006 test3 test4
test1 test2 41:375007 test3 test4
私が達成したいのは、次のコマンドを使用することです。
cat test_out.txt | awk "{if ($3 == 37~/\:*/ ) print $0;}"
上記は次の行を提供します。
test1 test2 37:375003 test3 test4
次の構文エラーが発生します。
Syntax Error The source line is 1.
The error context is
{if ( >>> == <<<
awk: 0602-502 The statement cannot be correctly parsed. The source line is 1.
答え1
~
構文は次の2項演算子を使用する必要があります。
string ~ regexp
文字列を正規表現と一致させるには、次のようにします。
<test_out.txt awk '$3 ~ /^37:[[:digit:]]+$/'
3番目のフィールドが拡張正規表現({print}
基本ジョブの略語)と一致するレコードを印刷します。{print $0}
^37:[[:digit:]]+$
ERE構文から:
^
トピックの先頭に一致[...]
:セット内のすべての文字または組み合わせ要素と一致します。[:digit:]
上記のセットは、ロケールで10進数に分類されたすべての文字を表します(ほとんどのシステムでは0123456789に制限されています)。他の10進数と一致しない場合は、0123456789
サポートされていないPOSIX文字クラスに変更してください。また、動作しますが、一部の実装では他の文字と一致する可能性があります。mawk
0-9
mawk
awk
+
上記の項目の1つ以上を対象としています。ここには1つ以上の数字があります$
トピックの終わりと一致します。
次の部分が数字で構成されているかどうか気にしない場合、37:
正規表現は^37:
(37:
トピックの先頭)です。
別の方法は次のとおりです。
<test_out.txt awk '$3 + 0 == 37'
+ 0
数値演算は、最初の数字の後のすべての項目を無視し、数値にawk
変換しようとします。$3
これは一致します37:anything
が、一部の実装と一致する可能性がある37.0;whatever
1、13.7e+1
も一致します。標準を使用しても一部の実装では機能しません。0x25#xxx
awk
+37+38
+$3 == 37
awk
37
シェル変数(ここ)から来る値の場合、シェルで正規表現を構成し、それをment変数に渡すことawk
ができます。ENVIRON
var=37
ERE='^'$var':[[:digit:]]+$' <test_out.txt awk '$3 ~ ENVIRON["ERE"]'
または、awk
v
シェル変数から変数²を作成します。
var=37
<test_out.txt awk -v n="$var" '$3 ~ "^" n ":[[:digit:]]+"'
次のようにシェル変数をawk
コードに拡張しないでください。
<test_out.txt awk '$3 ~ /^'"$var"':[[:digit:]]+$/'
これはしばしばコマンドインジェクションの脆弱性(最悪の脆弱性の種類)が発生するためです。
あなたの試みに関するいくつかのコメント:
- すでに同じです。@RudyCが指摘、awkコードの周りに二重引用符を使用しました。シェルはそこでパラメータ拡張を実行するため、
$3
シェルスクリプトの3番目のパラメータ値と$0
スクリプト名が拡張されます。 $3 == 37 ~ /\:*/
。==
次より高い優先順位~
。だからそれは($3 == 37) ~ /\:*/
。これは\:*
正規表現を比較結果と一致させます($3
37かどうかに応じて1または0)。\:*
正規表現が指定されていないため\:
指定されていません。 textと一致するには単独:
です:
。:*
ゼロ以上になるので、:
文字列には最小0:
が含まれているので、何でも一致します。*
正規表現でゼロ以上の前の項目と一致します。*
これをゼロ以上の文字に一致するシェルワイルドカードと混同する可能性があります。正規表現では、ゼロ個以上の文字は単一文字に一致する演算子.*
です。.
awk
文の形式はcondition {action}
次のとおりです。状況または行動省略可能です。お客様の場合は省略しました。状況そしてif
使用行動、{print $0}
デフォルト値を使用します。行動。これが機能している間は非常にユーザーフレンドリーでawk
はないかもしれませんawk
。- ほとんど意味のないファイルを
cat
リンクしたことがあります。cat
シェルはリダイレクトを使用してファイル自体をawk
標準入力として開くことができるため、プロセスを節約し、パイプを介してアイテムをプッシュする必要はありません。ファイル名をパラメータとして渡すと、awk
ファイルは自動的に開きます。
1少なくともいくつかの実装(たとえば、POSIXモードのGNU)では、小数基数文字がロケールにあり、ロケールにはないと仮定します.
。,
awk
awk
²-v
バックスラッシュは、ENVIRON
一般的に使用するのがより安全になるようにマングリングされています。
答え2
"
最初の間違いは、スクリプトで二重引用符を使用することですawk
。これにより、シェルは$3
シェル内のすべての項目に拡張されます(この場合は空の文字列になる可能性があります)。'
代わりに、単一引用符またはファイルを使用してください。
次に、他の回答に示すように、操作に適した正しい正規表現を使用してください。