Por que o awk imprime em cadeias não nulas e números positivos?

1

Tenho notado alguns exemplos de awk que usam 1 em vez de print para imprimir $0 (por exemplo, Para economizar espaço, normalmente uso '1' . E neste site).

Esta é uma prática documentada / segura, ou está sujeita a quebrar algumas versões; passado, presente ou futuro?

Aqui estão alguns exemplos:

echo 'a-does-print-$0' | awk '"x"'    
echo 'b-does-print-$0' | awk '$0'   
echo 'c-does-print-$0' | awk '1'
echo 'd-does-print-$0' | awk '(1-2)'  
echo 'd-does-print-$0' | awk '{$0="abc"}1'  

echo 'nothing-prints' | awk '{$0="abc"}'  
echo 'nothing-prints' | awk '$999' 
echo 'nothing-prints' | awk '(1-1)'  
echo 'nothing-prints' | awk '1-1' 
echo 'nothing-prints' | awk '0' 
echo 'nothing-prints' | awk 'unsetVar' 
echo 'nothing-printw' | awk ''

echo 'crashes' | awk '-3.14159'
echo 'crashes' | awk '-2' 
echo 'crashes' | awk '-1'
    
por Peter.O 08.03.2012 / 16:51

2 respostas

7

Então ... o formato de um programa awk é uma série de instruções EXPRESSION { ACTION } . Se você omitir a parte ACTION , ela assumirá print , e se você omitir o EXPRESSION , ele corresponderá a tudo. assim isso imprime tudo:

awk 1

Porque sua expressão ( 1 ) é avaliada como "true" (e você não tem ação). Isto é verdade para todos os exemplos "x-does-print", dado que sua entrada de amostra todos eles têm um não zero e não nulo EXPRESSION e não %código%. Dada uma linha de entrada vazia, ACTION no segundo exemplo não saída de qualquer coisa.

Da mesma forma, seus exemplos de "nada" além do primeiro têm uma expressão que é avaliada como "false" (uma string vazia ou numérico 0). O exemplo $0 funciona de maneira diferente: imprime nada porque não tem instruções de impressão. Dado um linha de entrada longa com pelo menos 999 campos, o segundo exemplo ( {$0="abc"} ) iria de fato imprimir a linha.

Isso é fundamental para como o $999 opera. Então, com certeza, está documentado e não vai quebrar.

Observe que seus exemplos de "travamentos" não ocorrem de fato; você acabou de cometeu um erro básico na sintaxe da sua shell. O awk interpreta argumentos começando com awk como opções de linha de comando. Citando eles não mude qualquer coisa. Se você quiser passar números negativos assim, você precisa prefixar seu programa awk com - para indicar ao awk que deve parar as opções de processamento:

echo 'crashes' | awk -- -3.14159

Imprimirá "falhas", pois -- não é uma string vazia nem numérico 0.

    
por 08.03.2012 / 17:22
1

De o manual GNU awk :

Many programming languages have a special representation for the concepts of “true” and “false.” Such languages usually use the special constants true and false, or perhaps their uppercase equivalents. However, awk is different. It borrows a very simple concept of true and false from C. In awk, any nonzero numeric value or any nonempty string value is true. Any other value (zero or the null string, "") is false.

Sim, esse uso é portátil e seguro para o futuro.

Sidenote, isso mostra seu segundo exemplo,

echo 'b-does-print-$0' | awk '$0'  

não imprime todas as linhas, apenas as que awk interpreta como uma string verdadeira, isto é, uma linha vazia ou uma linha contendo apenas uma maneira de escrever o número 0 ( 0 , 00 , 0.0e3 , -.0 ,…).

    
por 08.03.2012 / 17:23