Onde as seqüências de escape são necessárias ao usar o til ~ ~ no awk?

5

Eu tenho uma variável pattern com valor abaixo:

\"something//\anotherthing'

e um arquivo com o conteúdo abaixo:

\"something//\anotherthing'
\"something//\anotherthing
\"something/\anotherthing'
\"something\anotherthing'
\"something\/\/\\anotherthing'

Quando compara uma linha lida do arquivo com o padrão no ambiente com o 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 eu faço o mesmo com o operador ~ , os testes nunca correspondem. (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 duplicar as 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 que o duplo escapa em resultado da impressão de ENVIRON["patt"] na segunda coluna.

Pergunta:

Onde a sequência de escape em awk acontece ao usar o operador de comparação til% ~ ? em $0 (ou $1 , $2 , ...) ou em ENVIRON["variable"] ?

    
por αғsнιη 23.05.2018 / 11:24

2 respostas

6

O operador ~ faz correspondência de padrões, tratando o operando à direita como uma expressão regular (estendida) e a da esquerda como uma sequência. POSIX diz:

A regular expression can be matched against a specific field or string by using one of the two regular expression matching operators, '~' and "!~". These operators shall interpret their right-hand operand as a regular expression and their left-hand operand as a string.

Portanto, ENVIRON["patt"] é tratado como uma expressão regular e precisa ter todos os caracteres que são especial em EREs para ser escapado, se você não quer que eles tenham seus significados regulares de ERE.

Observe que não se trata de usar $0 ou ENVIRON["name"] , mas os lados esquerdo e direito do til. Isso levaria as linhas de entrada (em $0 ) como a expressão regular para correspondência:

str=foobar awk 'ENVIRON["str"] ~ $0 { 
     printf "pattern /%s/ matches string \"%s\"\n", $0, ENVIRON["str"] }'
    
por 23.05.2018 / 11:33
2

Um \ em uma expressão regular escapa do caractere seguinte ou introduz uma seqüência de escape. Para corresponder um literal \ a uma expressão regular, que é o que o operador ~ faz em awk , seria necessário usar \ (o que você faz no último exemplo da pergunta). Em uma comparação de string, isso não é necessário.

    
por 23.05.2018 / 11:32