O comando getline no awk é seguro para uso?

O comando getline no awk é seguro para uso?

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

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

Não é uma boa solução, pois unirá linhas independentemente do conteúdo e não processará mais linhas, se necessário. E você deve evitar usar getline.

Afirma que devemos evitar a getlinefunção em awk. Então minhas perguntas são,

  • É seguro usar getlinea função no awk?
  • Em que circunstâncias devemos usar e getlineem quais casos não devemos?
  • Se esta função produz resultados inesperados, por que não enviamos um relatório de bug?

Responder1

getlineA maioria das pessoas discuteestilo de codificaçãochão.

É estranho ao awkprocessamento normal fazer com que o código processe 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 do código. É fácil perder a noção do fato de que incrementa NR, FNR, pode alterar FILENAME.

Outra coisa que não se deve esquecer ao utilizá-lo é verificar seu valor de retorno, pois retornará 0 em EOF ou <0 em caso de erro.

Então não é getlineou if/while (getline) ..., é:

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

Ou:

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

A maioria dos usos de getlinepode ser revertida usando uma abordagem semelhante à de uma máquina de estados.

Em vez de:

/pattern/ {getline; print}

O que provavelmente está errado e deveria 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 sepadrãoé correspondido em duas linhas consecutivas.

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

while ((getline a < "a") > 0 && (getline b < "b") > 0) {
  ....

informação relacionada