
pattern
次の値を持つ変数があります。
\"something//\\anotherthing'
以下を含むファイル:
\"something//\\anotherthing'
\"something//\\anotherthing
\"something/\anotherthing'
\"something\anotherthing'
\\"something\/\/\\\\anotherthing'
ファイルから読み取った行を==
環境のパターンと演算子と比較すると、予想される出力が得られます。
patt="$pattern" awk '{print $0, ENVIRON["patt"], ($0 == ENVIRON["patt"]?"YES":"NO") }' OFS="\t" file
\"something//\\anotherthing' \"something//\\anotherthing' YES
\"something//\\anotherthing \"something//\\anotherthing' NO
\"something/\anotherthing' \"something//\\anotherthing' NO
\"something\anotherthing' \"something//\\anotherthing' NO
\\"something\/\/\\\\anotherthing' \"something//\\anotherthing' NO
ただし、演算子で同じ操作を実行すると、~
テストは一致しません。 (YES
上記のように最初の行に期待しています):
patt="$pattern" awk '{print $0, ENVIRON["patt"], ($0 ~ ENVIRON["patt"]?"YES":"NO") }' OFS="\t" file
\"something//\\anotherthing' \"something//\\anotherthing' NO
\"something//\\anotherthing \"something//\\anotherthing' NO
\"something/\anotherthing' \"something//\\anotherthing' NO
\"something\anotherthing' \"something//\\anotherthing' NO
\\"something\/\/\\\\anotherthing' \"something//\\anotherthing' NO
比較して問題を解決するには、~
エスケープを2回エスケープする必要があります。
patt="${pattern//\\/\\\\}" awk '{print $0, ENVIRON["patt"], ($0 ~ ENVIRON["patt"]?"YES":"NO") }' OFS="\t" file
\"something//\\anotherthing' \\"something//\\\\anotherthing' YES
\"something//\\anotherthing \\"something//\\\\anotherthing' NO
\"something/\anotherthing' \\"something//\\\\anotherthing' NO
\"something\anotherthing' \\"something//\\\\anotherthing' NO
\\"something\/\/\\\\anotherthing' \\"something//\\\\anotherthing' NO
ENVIRON["patt"]
2列目の印刷結果でダブルエスケープを確認してください。
質問:
エスケープシーケンスはどこにありますか?アッチルダ~
比較演算子を使用すると、これは起こりますか?オン$0
(または$1
、、$2
...)またはオンENVIRON["variable"]
?
答え1
この~
演算子はパターンマッチングを行い、右側のオペランドを(拡張)正規表現として扱い、左側のオペランドを文字列として扱います。POSIX説明する:
2つの正規表現一致演算子
'~'
と"!~"
。これらの演算子は、右側のオペランドを正規表現として解釈し、左側のオペランドを文字列として解釈する必要があります。
so はENVIRON["patt"]
正規表現として扱われ、以下が必要です。EREのすべての特殊文字一般的なERE意味を持たない場合は、エスケープできます。
これは$0
またはを使用するのではなく、チルダの左右ENVIRON["name"]
に関連します。これは、入力行(in $0
)を一致させる正規表現として使用します。
str=foobar awk 'ENVIRON["str"] ~ $0 {
printf "pattern /%s/ matches string \"%s\"\n", $0, ENVIRON["str"] }'
答え2
\
正規表現のAは、次の文字をエスケープするか、エスケープシーケンスを導入します。\
リテラルを正規表現と一致させるには(~
演算子で行われたアクションawk
)、次のものを使用する必要があります\\
(質問の最後の例でこれを実行します)。文字列比較ではこれは必要ありません。