Eu tenho uma pattern
variável com o valor abaixo:
\"something//\\anotherthing'
e um arquivo com o conteúdo abaixo:
\"something//\\anotherthing'
\"something//\\anotherthing
\"something/\anotherthing'
\"something\anotherthing'
\\"something\/\/\\\\anotherthing'
Quando comparo uma linha lida do arquivo com o padrão no ambiente com ==
operador, obtenho a saída esperada:
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
Mas quando faço o mesmo com o ~
operador, os testes nunca coincidem. (Eu esperava YES
na primeira linha, como acima):
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
Para corrigir o problema com a ~
comparação, preciso escapar duas vezes das fugas:
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
Observe os escapes duplos no resultado da impressão ENVIRON["patt"]
na segunda coluna.
Pergunta:
Onde a sequência de escape no awk~
acontece ao usar o operador de comparação til ? em $0
(ou $1
, $2
, ...) ou em ENVIRON["variable"]
?
O
~
operador faz a correspondência de padrões, tratando o operando da direita como uma expressão regular (estendida) e o da esquerda como uma string. POSIX diz:So
ENVIRON["patt"]
é tratado como uma expressão regular e precisa ter todos os caracteres que são especiais em EREs para serem escapados, se você não quiser que eles tenham seus significados ERE regulares.Observe que não se trata de usar
$0
ouENVIRON["name"]
, mas os lados esquerdo e direito do til. Isso levaria as linhas de entrada (em$0
) como a expressão regular para corresponder:A
\
em uma expressão regular escapa do caractere seguinte ou introduz uma sequência de escape. Para combinar um literal\
com uma expressão regular, que é o que o~
operador faz emawk
, seria necessário usar\\
(o que você faz no último exemplo da pergunta). Em uma comparação de strings, isso não é necessário.