Escapando a barra invertida com o awk no OSX

0

Estou tentando corresponder \ N em um campo de um arquivo csv.

Eu tentei

awk -F "|" '($12=="\N") {print}' ./filename.csv
awk -F "|" '($12==\N) {print}' ./filename.csv
awk -F "|" '($12==\N) {print}' ./filename.csv
awk -F "|" '($12==\\N) {print}' ./filename.csv

nada funciona até agora

    
por Bob 01.12.2016 / 13:01

1 resposta

2

No tipo Bourne (como bash ), shells do tipo Csh ou rc, use:

awk -F'|' '$12 == "\N"'

Em strings awk, a barra invertida é usada para introduzir sequências de escape semelhantes a C como \b para backspace, \n para newline, 3 para sequências octal ... Você precisa de \ para a barra invertida. O \N em si não é atualmente uma sequência de escape conhecida em qualquer implementação awk que eu saiba.

Algumas implementações awk tratam "\N" como \ e N , algumas como N , algumas (gawk) como N com uma mensagem de aviso emitida. POSIX deixa o comportamento não especificado.

Observe que isso também se aplica a strings transmitidas como:

awk -F'|' -v value='\N' '$12 == value'

Ou:

awk -F'|' '$12 == value' value='\N'

Você pode querer usar o ambiente para passar um valor como está sem ter que se preocupar em escapar de caracteres especiais para awk :

VALUE='\N' awk -F'|' '$12 == ENVIRON["VALUE"]'

Também se aplica a literais de expressões regulares expressas como /.../ , como em:

awk -F'|' '$12 ~ /\N/'

No entanto, é ainda mais complicado pelo fato de que a barra invertida está sobrecarregada como o introdutor da seqüência de escape (para \n , \b ...) e como um operador de cotação para regexps ( \. or \$ ... para remover seu significado especial de operador de expressão regular). POSIX não está claro (e nem sequer corresponde à realidade em alguns casos) em alguns casos de canto (como em /\./ ou // ou /[5]/ ). Novamente, usar ENVIRON pode ajudar, embora nem sempre. Por exemplo:

R='[\]' awk '$0 ~ ENVIRON["R"]'

foi criado para corresponder à barra invertida no POSIX, mas retorna um erro em todas as implementações awk que eu conheço. Melhor sempre escapar do \ mesmo dentro de [...] se for para ser tomado literalmente, para estar no lado seguro.

Observe que, para o shell fish , você precisa de outra camada de escape, como para fish (ao contrário da maioria dos outros shells), \ é especial entre aspas simples. Então você precisa:

awk -F'|' '$12 == "\\N"'

lá. Embora

awk -F'|' '$12 == "\\N"'

também funcionará.

env 'V=\N' awk -F'|' '$12 == ENVIRON["V"}'

também deve funcionar (em fish e outras famílias de shell).

    
por 01.12.2016 / 13:38