Quando o awk tratará o caractere de nova linha como ';' e quando não?

1

Estou lendo o famoso tutorial do awk no link .

Em que mencionou To be precise, in the original AWK you can insert a new line character after the curly braces, and at the end of a command, but not elsewhere.

Eu recebi o seguinte teste de comando awk de várias linhas no meu host mac e remoto, com awk e gawk :

  awk '$0 !~ /special_signal/  \
       { my_dict[$1] += $2 }
       END { for (uid in my_dict)   \
             if (my_dict[uid] > 1)  \
             print uid, my_dict[uid]}' raw_data | sort -nk2

O comando awk original de uma linha do código awk acima é:

awk '$0 !~ /special_signal/ { my_dict[$1] += $2 } END { for (uid in my_dict) if (my_dict[uid] > 1) print uid, my_dict[uid]}' raw_data | sort -nk2

Através dos meus experimentos. Eu encontrei em ambos os awk e gawk , o primeiro \ é essencial, sem ele, o código se comportará diferentemente em comparação com o one-liner original. O efeito do caractere de nova linha é idêntico ao ;

Mas o segundo e terceiro \ após for (uid in my_dict) e if (my_dict[uid] > 1) em todas essas duas edições awk são desnecessários.

Eu os removi, o código múltiplo age exatamente como o de uma linha.

Depois, substituí o segundo e o terceiro \ por ; , o que levará o código de várias linhas a produzir um resultado errado.

Isso provou ainda mais que se eu adicionar um caractere de nova linha depois de for (uid in my_dict) e if (my_dict[uid] > 1) , eles conectarão esses dois blocos de código com o código da próxima linha, agem como \ .

Minha conclusão parece conflitar com o tutorial.

Então, de fato, em quais circunstâncias o awk tratará a nova linha como ; e como tratá-la como \ ?

PS: por causa do teste, fiz um conteúdo de teste para raw_data :

Tom 2
Tom 5
Jack 3
Mary 5
special_signal 5
Tim 10
Don 22
Jan 3
Jack 8
special_signal 10
    
por Zen 08.02.2015 / 14:14

1 resposta

3

A diferença entre suas linhas de exemplo é: O comando pode ser concluído nesse ponto? Um padrão pode ficar sozinho; Nesse caso, {print} é assumido. A próxima linha é considerada um segundo comando (não a segunda parte do primeiro); assume-se que o padrão é sempre verdadeiro.

Mas dentro de uma estrutura de controle ( for , if ) você não pode terminar o comando naquele ponto, portanto, é claro que o comando continua na próxima linha.

É semelhante no código shell:

echo foo &&
echo bar

é interpretado de maneira diferente de

echo foo
&& echo bar

então você precisa

echo foo \
&& echo bar

Com a diferença para awk , só funciona uma maneira. Mas pode haver casos semelhantes.

    
por 08.02.2015 / 14:41

Tags