Atribuição entre chaves vs chaves externas no awk

2

De esta pergunta , respondo com esta solução:

awk 'FNR==NR{a[FNR]=$2;next}{$NF=a[FNR]}1' file2 file1

Funciona como esperado.

Mas a primeira solução que pensei é:

$ awk 'FNR==NR{a[FNR]=$2;next}$NF=a[FNR]' file2 file1
A 63 9 6
B 45 3 5

Não funciona, desde quando awk não imprimiu a primeira linha em file1 . Isso me deixa surpresa, e não sei porque awk pula a primeira linha.

Aqui estão alguns exemplos:

$ awk 'FNR==NR{next}$1=123' file2 file1 
123 23 8 T
123 63 9 9
123 45 3 J  

$ awk 'FNR==NR{a[FNR]=$2;next} FNR in a' file2 file1
A   23  8   T
A   63  9   9
B   45  3   J

Você pode ver, nos dois exemplos, que awk funciona conforme o esperado. Primeiro, atribuir um novo valor a um campo do valor de registro afetado do registro atual e awk imprimir novo valor. A segunda mostra que awk teve o registro de todos os processos em file2 , nenhum registro é ignorado.

Por que awk pula a primeira linha da minha primeira solução?

Eu uso gawk 4.0.1 e também testei com mawk 1.3.3 .

    
por cuonglm 21.07.2014 / 10:42

2 respostas

0

Depois de algumas pesquisas, encontrei a resposta.

Primeiro, de acordo com este :

Expression Patterns

An expression pattern will be evaluated as if it were an expression in a 
Boolean context. If the result is true, the pattern will be considered to 
match, and the associated action (if any) will be executed. If the result is 
false, the action will not be executed.

Portanto, no meu exemplo, $NF=a[FNR] será considerado como um padrão de expressão. Como o documento disse, o resultado da atribuição é avaliado como true ou false .

No meu exemplo, o resultado da atribuição é 0 , que é avaliado como false no contexto booleano, fazendo com que o padrão seja considerado como não correspondido, nenhuma ação seja executada.

Nota para @Michael Homer

Este é um exemplo para mostrar que The assignment to m returned the value assigned. in awk está incorreto.

$ awk 'function test() {a=2} BEGIN{print test()}'
<blank line>

$ perl -e 'sub test {$a=2}; print test'
2

Você pode ver qual atribuição retorna em awk example?

awk 'n=(m=5);END{print n}' prints 5 devido a efeito colateral , não significa awk valor de retorno da atribuição.

    
por 21.07.2014 / 11:33
9

Você tem:

$NF=a[FNR]

como a condição final (aquela que determina se deve ser impressa). Atribuições retornam o valor atribuído, neste caso a[FNR] . A primeira linha do arquivo de dados da pergunta vinculada é:

A   0

a[FNR] é inicializado em $2 . Isso significa que o valor de a[FNR] é 0 , que é um valor falso para awk. Isso significa que a atribuição é falsa, o que torna o condicional falso e suprime o comportamento de impressão padrão. Se mudarmos o arquivo de dados para:

A   1
A   6   
B   0

a primeira linha será impressa, mas a última será perdida.

Então não é que a primeira linha esteja ausente, é qualquer linha onde o último campo é zero (ou vazio). Acontece que a primeira linha e apenas a primeira linha era assim.

    
por 21.07.2014 / 11:12

Tags