
Recebi comentários estranhos ao postar uma awk
resposta no SO que usa a getline
funçã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 getline
função em awk
. Então minhas perguntas são,
- É seguro usar
getline
a função no awk? - Em que circunstâncias devemos usar e
getline
em quais casos não devemos? - Se esta função produz resultados inesperados, por que não enviamos um relatório de bug?
Responder1
getline
A maioria das pessoas discuteestilo de codificaçãochão.
É estranho ao awk
processamento 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 é getline
ou if/while (getline) ...
, é:
if/while ((getline) > 0) { .... }
Ou:
if/while ((getline < "file") > 0) {...}
A maioria dos usos de getline
pode 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, getline
tudo 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) {
....