O comando getline in awk é seguro de usar?

4

Recebi comentários estranhos ao postar uma resposta awk no SO que usa a função getline . Aqui é o link para essa resposta.

Depois de postar minha resposta, um usuário criou o comentário abaixo, ( eu não o critico. )

Not a good solution, it will join lines regardless of content and not process more lines if needed. And you should avoid using getline.

Ele afirma que devemos evitar a função getline em awk . Então minhas perguntas são,

  • É seguro usar a função getline no awk?
  • Em que circunstâncias devemos usar getline em quais casos não devemos?
  • Se esta função produzir resultados inesperados, por que não arquivamos um relatório de erros?
por Avinash Raj 27.06.2014 / 18:31

1 resposta

7

A maioria das pessoas discute sobre getline no estilo de codificação .

É alheio ao processamento normal de awk fazer o código processar um registro por vez.

getline (quando não usado como getline var < "file" ou "cmd" | getline ) extrai o próximo registro (possivelmente do próximo arquivo) no meio da instrução de código. É fácil perder a noção do fato de que isso incrementa NR, FNR, pode alterar o FILENAME.

Outra coisa que você não deve esquecer ao usá-lo é verificar seu valor de retorno, pois ele retornará 0 no EOF ou < 0 no erro.

Portanto, não é getline ou if/while (getline) ... , é:

if/while ((getline) > 0) { .... }

Ou:

if/while ((getline < "file") > 0) {...}

A maioria dos usos de getline pode ser mudada usando uma abordagem semelhante a uma máquina de estado.

Em vez de:

/pattern/ {getline; print}

O que provavelmente está errado e deve ser escrito:

/pattern/ && (getline) > 0 {print}

Você faria:

found_pattern {print; found_pattern=0}
/pattern/{found_pattern=1}

Observe também como os dois são diferentes se padrão for correspondido em duas linhas consecutivas.

Agora, desde que você saiba disso, getline está bem. Se você quiser processar vários arquivos ao mesmo tempo, precisará getline , mas lembre-se de verificar o valor de retorno:

while ((getline a < "a") > 0 && (getline b < "b") > 0) {
  ....
    
por 27.06.2014 / 19:00

Tags