o que getline faz dentro do awk?

Tenho o seguinte awk script que obtém o seguinte arquivo de entrada, input.txt e produz a saída abaixo. Alguém pode, por favor, desmembrar como esse awk script funciona? Eu gastei um pouco de tempo nisso e não está fazendo muito sentido.


Entrada:

$ cat input.txt

FINISHED RSYNCJOBNA 20140502 0021 2182096 2082096 6 5 2014820905820902 10:02:15 2014820905820902 10:56:42 0:54:27 INITIATED RSYNCJOBNA 20140502 0022 3282096 3182096 6 5 2014820905820902 15:31:06 0:06:04 ce eque** 

Resultado:

RSYNCJOBNA|0021|20140502|10:02:15|10:56:42|0:54:27|FINISHED RSYNCJOBNA|0022|20140502|15:31:06| |0:06:04|INITIATED 

Comando para obter a saída acima:

awk -v OFS="|" "/FINISHED|INITIATED/ { status = $1; getline; jobname = $1; getline; sequence = $2; date = $1; getline; start = $2; getline; if (status == "FINISHED") { end = $2; getline } else { end = " " } runtime = $1; print jobname, sequence, date, start, end, runtime, status; }" input.txt 

Meu entendimento é que /FINISHED|INITIATED/ {} significa que os comandos dentro das chaves só serão executados em linhas que correspondam a FINISHED ou INITIATED mas tanto quanto posso dizer pela saída, o script parece estar analisando todas as linhas. O que está acontecendo?

Comentários

  • O que exatamente você ' não entende? Nada? Nesse caso: Devemos ler o manual do awk para você? Caso contrário: seja preciso. Os dados são lidos em variáveis e produzidos em ordem diferente.
  • Eu não ' t sei o que a função getline no comando acima faz. E também se dermos o padrão como este /FINISHED|INITIATED/, awk procura a linha correspondente e faz a operação apenas naquela linha particular. Mas a operação foi realizada em todas as linhas. Como?
  • @HaukeLaging O que Dados são lidos em variáveis e produzidos em ordem diferente significa linha?

Resposta

A função getline lê a próxima linha e move o script para ela. chamadas getline consecutivas passam para a próxima linha. Isso talvez seja mais fácil de entender com um exemplo:

$ cat input.txt foo 1 2 $ awk "/foo/{print; getline; print; getline; print}" input.txt foo 1 2 

Como como você pode ver acima, o script processará a primeira linha porque corresponde a foo. Cada chamada para getline lerá a linha após a atual, então as print chamadas subsequentes estão imprimindo as próximas linhas.

Resposta

Se você não sabe o que uma função awk faz, então a estratégia usual é para dar uma olhada na página de manual:

getline

Defina $ 0 do próximo registro de entrada; defina NF, NR, FNR, RT

O bloco de comando é realmente executado apenas duas vezes. As outras linhas são tratadas via getline de dentro do bloquear.

Isso pode ser reescrito para:

/FINISHED|INITIATED/ { status = $1; line_number=0; next; } { line_number++; } line_number==1 { jobname = $1; } line_number==2 { sequence = $2; date = $1; } ... 

Comentários

  • O que acontece se o próximo registro estiver vazio?
  • @AvinashRaj Nem o seu código nem a minha alternativa examinam o conteúdo das linhas (com exceção de /FINISHED|INITIATED/ ). As linhas são apenas contadas. Os dados devem ser organizados exatamente (de um parsi de awk perspectiva) da maneira que você mostrou, caso contrário, o código irá quebrar.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *