getline 在 awk 中做什么?

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/ {}意味着大括号内的命令只会在匹配 或 的行上运行FINISHEDINITIATED但据我从输出中可以看出,脚本似乎正在解析全部线。这是怎么回事?

答案1

getline函数读取下一行并将脚本移至该行。因此,连续的getline调用会移动到下一行。通过一个例子也许更容易理解:

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

正如您在上面看到的,脚本将处理第一行,因为它匹配foo.每次调用getline都会读取当前行之后的行,因此后续print调用将打印下一行。

答案2

如果您不知道awk函数的作用,那么通常的策略是查看手册页:

获取线

从下一个输入记录开始设置$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; }
...

相关内容