Awkで正規表現を変数に保存するときに、正規表現が必要なときはいつでもその変数を使用できますか?
AhoのAWKプログラミング言語は次のように言います。
文字列一致パターンに注意してください。
/Asia/
は略語です
$O ~ /Asia/
テキストファイルがあります。
$ cat f1
line 1; li
ne
2
line 3
lin
e 4
次の2つの方法が機能する理由
$ awk -v pat='in' '{if (match($0, pat)) print $0; } ' f1
line 1; li
line 3
lin
$ awk -v pat='in' ' $0 ~ pat {print $0} ' f1
line 1; li
line 3
lin
そして従う人もいません。
$ awk -v pat='in' ' pat {print $0} ' f1
line 1; li
ne
2
line 3
lin
e 4
?
ありがとうございます。
答え1
/foo/
「一人で」の略語だけです$0 ~ /foo/
。
... ~ /.../
or ... ではmatch(/.../, ...)
正規表現に対する一種の参照演算子であるのに対し、他のコンテキストでは数字 (0 または 1) で構文解析する演算子に近いです。
この二重の意味は少し混乱するかもしれません。には二重の意味/あいまいさがたくさんありますawk
。
/foo/
正規表現と一致するかどうかに応じて$0
1 または 0 に拡張されますが、正確に一致する場合は拡張されず、ここでは短縮されませんfoo
。"1" ~ /foo/
または の場合、さまざまな実装が異なる動作をしていることがわかります。"1" ~ "1"
$0
foo
/foo/
($0 ~ /foo/)
"1" ~ (/foo/)
"1" ~ +/foo/
var
のみvar
。
var
as 条件は、変数が数字または数字の文字列で、ゼロ以外の数字で解決される場合、または文字列で空でない文字列で解決される場合はtrueを意味します。
with として宣言された変数は、-v var=value
数値と文字列のように見える場合に数値文字列として扱うことができる変数の1つです。
awk -v var=in 'var {print "x"}'
x
in
数字や空の文字列のように見えないため、各レコードに印刷します。
awk -v var=0 'var {print "x"}'
印刷されませんx
。と:
awk 'BEGIN{var = "0"}; var {print "x"}'
文字列変数で明示的に宣言されたx
すべてのレコードを印刷します。var
したがって、数字のように見えますが、数字とは見なされません。
これは二重意味のもう一つです。状況によっては、変数を数字または文字列として扱うことができます。また、>
コンテキストに従って比較演算子またはリダイレクト演算子として扱われます(これも実装ごとに動作が異なるいくつかのあいまいなケースの1つです)。
次のタスクも実行できます。
awk '{print /foo/ + /bar/}'
これは次のとおりです。
awk '{print ($0 ~ /foo/) + ($0 ~ /bar/)}'
しかし、代わりに接続を使用すると+
awk '{print /foo/ /bar/}'
/RE/
演算子と/
除算演算子の間にあいまいさがあるため、これは機能しません。わからない場合は、かっこを使用してください。
awk '{print (/foo/) (/bar/)}'
ただし、保存された正規表現やバックスラッシュを含めることができるすべての項目を使用しないでください-v
。 ANSIエスケープシーケンスが拡張されているためです(GNU awk
4.2以降、で始まり@/
終わる値/
も問題)。代わりに環境変数を使用する必要があります。
RE='\.txt$' awk '$0 ~ ENVIRON["RE"] {...}'
例えば。