o que o getline faz dentro do awk?

1

Eu tenho este seguinte script awk que pega o seguinte arquivo de entrada, input.txt e produz a saída abaixo. Alguém pode, por favor, dedicar um tempo para decifrar como esse script awk funciona? Passei um pouco de tempo nisso e não faz 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**

Saída:

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 correspondentes a FINISHED ou INITIATED , mas, tanto quanto eu posso dizer a partir da saída, o script parece estar analisando de todas linhas. O que está acontecendo?

    
por Avinash Raj 03.05.2014 / 09:38

2 respostas

9

A função getline lê a próxima linha e move o script para ela. Portanto, as chamadas getline consecutivas são movidas para a próxima linha. Talvez isso 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 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, portanto, as chamadas print subseqüentes estão imprimindo as próximas linhas.

    
por 03.05.2014 / 14:47
2

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

getline

Set $0 from next input record; set NF, NR, FNR, RT

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

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; }
...
    
por 03.05.2014 / 10:37

Tags