O que é permitido fazer com NF em um bloco ou função de código awk?

6

Referência: O padrão POSIX para o utilitário awk .

Uma coisa que realmente sinto falta em awk é a capacidade de unir uma matriz a um delimitador, como com o comando join em Perl, normalmente feito para saída imediata.

Em vez disso, acabo escrevendo código como

for (key in array)
    joined_string = (joined_string ==  "" ? array[key] : joined_string "," array[key])

print joined_string

ou

joined_string = array[1]
for (i = 2; i <= length(array); ++i)
    joined_string = joined_string "," array[i];

print joined_string

No entanto, awk pode fazer isso por mim se eu alterar os campos atuais:

OFS="," # (would probably do this in BEGIN)

n = 0
for (key in array)
    $(++n) = array[key]

print

Eu acredito que isso é perfeitamente legal. No entanto, isso produzirá lixo na saída se o registro de entrada atual tiver mais campos do que a matriz array possui entradas (o "lixo" seria dado do arquivo de entrada). Seria bom poder fazer

OFS = "," # (would probably do this in BEGIN)

n = 0
for (key in array)
    $(++n) = array[key]

NF = n
print

Não consigo encontrar nenhum texto na norma dizendo que a modificação de NF é permitida, mas nenhum texto diz que não é permitido ou que invoca um comportamento indefinido. A informação que eu posso encontrar é que getline define NF . Isso não diz que eu não tenho permissão para escrever minha própria função ou bloco de código que redefina NF , e dá uma precedência para fazer isso com a existência da função getline ".

Também é declarado que a atribuição a $0 é permitida e que isso redefine NF . Isso significa que o código a seguir seria melhor?

OFS = "," # (would probably do this in BEGIN)

$0 = ""
n = 0
for (key in array)
    $(++n) = array[key]

print

Duplica pergunta:

  1. A configuração NF é permitida?
  2. Essa última parte do código seria a maneira correta de unir uma matriz a um delimitador para saída?
por Kusalananda 19.06.2018 / 12:36

1 resposta

11

Até onde eu sei, não há texto standard documentando os efeitos colaterais da configuração de NF , ou mesmo se a configuração é permitida. O manual do Gawk (também publicado como Effective awk Programming ), que diz que tenta documentar Awk em geral e não (somente) a implementação GNU, inclui o seguinte :

Decrementing NF throws away the values of the fields after the new value of NF and recomputes $0. (d.c.)

com a advertência

CAUTION: Some versions of awk don’t rebuild $0 when NF is decremented.

A menção "(dc)" significa que este é um "canto escuro" de Awk , ie um que é mal documentado (ou não é) e onde o comportamento pode variar de uma implementação para outra.

POSIX define variáveis especiais como

variables that are set by awk

mas não especifica se podem ser definidos por programas (como regra geral). Algumas das especificações das variáveis mencionam que podem ser modificadas (veja ARGC , ARGV ), outras que as conseqüências de alterá-las são definidas pela implementação ( ENVIRON ), outras ainda não mencionam nada, mas são "Obviamente" destinado a ser modificado pelo programa ( OFS etc.).

No caso de NF , a experimentação dá uma resposta parcial:

  • modificar NF funciona conforme documentado no GNU Awk e mawk também se comporta da mesma maneira;
  • as alterações para NF em O One True Awk são preservadas, mas não fazer com que $0 seja recalculado.

Então, eu diria que

  1. A configuração de NF é permitida, mas pode não ter efeitos colaterais além de definir o valor.
  2. Como a definição $0 é especificada por POSIX, a última variante está correta de acordo com a especificação. (É discutível se é o correto, pois ele perde $0 .)

A função em Como você converte uma matriz em uma string no awk? é interessante, mas como definido depende nas extensões GNU Awk e, portanto, não é uma resposta para essa pergunta.

(Outras variáveis que podem ser definidas, surpreendentemente, incluem NR e FNR , inclusive em TOTA. FILENAME , no entanto, não pode ser definido, ou melhor, definindo seu valor.) / p>     

por 19.06.2018 / 13:56

Tags