что делает getline внутри awk?

У меня есть следующий скрипт awk который принимает следующий входной файл input.txt и выводит результат ниже. Может кто-то, пожалуйста, потратьте время, чтобы сломать, как работает этот скрипт awk ? Я потратил немного времени на это, и это не имеет большого смысла.


Входные данные :

$ 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** 

Вывод:

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

Команда для получения вышеуказанного вывода:

 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 

Я понимаю, что /FINISHED|INITIATED/ {} означает, что команды внутри фигурных скобок будут выполняться только в строках, соответствующих либо FINISHED либо INITIATED но, насколько я могу судить по выводу, скрипт, похоже, разбирается со всеми строками , Что происходит?

Функция getline считывает следующую строку и перемещает скрипт к ней. Таким образом, последовательные вызовы getline переходят к следующей строке. Это, возможно, проще понять с помощью примера:

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

Как вы можете видеть выше, скрипт будет обрабатывать первую строку, потому что она соответствует foo . Каждый вызов getline будет читать строку после текущей, поэтому последующие вызовы печати печатают следующие строки.

Если вы не знаете, что делает функция awk , то обычной стратегией является просмотр справочной страницы:

GetLine

Установите $ 0 из следующей входной записи; набор NF, NR, FNR, RT

Блок команд выполняется только дважды. Другие строки обрабатываются через getline изнутри блока.

Это можно переписать следующим образом:

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