gawk notes(3)
> getline 控制输入
使用getline可以对输入进行更多的控制。用变量名作为参数传递给getline,getline能将数据读入到这个变量。
1: # gawk sample: g1
2: BEGIN {
3: getline aa
4: print aa
5: }
6: -----------------
7: datafile:
8: alpha
9: aaaaaaaaaaa
10: bbbbbbbbbbb
11: ccccccccccc
12: ddddddddddd
13: -----------------
14: gawk -f g1 < alpha
15: -----------------
16: output:
17: aaaaaaaaaaa
默认地,只是输出第一行。可以通过while循环,遍历标准输入中的行,将每行读取到变量中。
1: # gawk sample:g2
2: BEGIN {
3: while (getline holdname)
4: print holdname
5: }
6: -----------------
7: gawk -f g2 < alpha
8: -----------------
9: output:
10: aaaaaaaaaaa
11: bbbbbbbbbbb
12: ccccccccccc
13: ddddddddddd
当gawk的程序题(而不仅仅是BEGIN块)中有语句时,gawk自动将输入中的每一行读取到$0中。
而getline的运行独立于gawk的自动读取和$0。当getline读到某个变量值的时候,并不修改$0,也不修改当前记录得到任何字段($1-$n)。但是,如果文件读取过程中的游标却是被$0和getline依次修改,从这个角度说,getline和gawk的自动读取是平级的。
1: # gawk sample: g3
2: {
3: print NR,"$0:", $0
4: getline aa
5: print NR,"aa:", aa
6: }
7: -----------------
8: gawk -f g3 < alpha
9: -----------------
10: output:
11: 1 $0 aaaaaaaaaaa
12: 2 aa bbbbbbbbbbb
13: 3 $0 ccccccccccc
14: 4 aa ddddddddddd
利用getline和gawk自动读取的相互独立,可以实现如下的例子:
1: # gawk sample: g4
2: {
3: print "line #", NR, $0
4: }
5: /^b/ {
6: getline hold
7: print "Skip this line:", hold
8: print "Previous line began with:", $1
9: print ">>>> Finished processing line #",NR
10: print ""
11: }
12: ----------------
13: gawk -f g4 < alpha
14: ----------------
15: output:
16: line #1 aaaaaaaaaaa
17: >>>> Finished processing line #1
18:
19: line #2 bbbbbbbbbbb
20: Skip this line: ccccccccccc
21: Previous line began with: bbbbbbbbbbb
22: >>>> Finished processing line #3
23:
24: line #4 ddddddddddd
25: >>>> Finished processing line #4
前面notes(2) 测试过gawk中多个pattern是顺序执行。对alpha文件中的四行数据,先被{}处理,然后被/^b/{}处理
aaaaaaaaaaa 只被{}处理;
bbbbbbbbbbb 先被{}处理,输出第一行;然后,被/^b/{}处理,由于getline与gawk自动读取相互独立,则此时getline读到的是ccccccccccc,同时由于getline不修改$0,$1-$n,所以此时$1中的值,还是上次gawk自动读取bbbbbbbbbbb时的值。getline将读文件的指针指向了第三行,故NR为3
ddddddddddd 只被{}处理。
> 协进程:双向I/O
协进程:与另一个进程并行运行的进程。
gawk从版本3.1开始,可以调用一个协进程直接与某个后台进程进行信息交换。协进程可用于C/S环境中,搭建SQL前端/后端,或者通过网络与远程系统交换数据。
gawk通过在启动后台进程的那个程序名称前面添加" |& "操作符的方式表示协进程。
协进程必须是一个过滤器(如:从表输入读取并写入到标准输出),并在每完成一行的处理之后,清空输出,而不是将多个输出累计用于后面的输出。当调用某命令作为协进程是,它通过一个双向管道连接到gawk程序,这样用户可以从这个协进程读取或者向其中写入。
1: to_upper
2: --------------------
3: #!/bin/bash
4: while read arg
5: do
6: echo "$arg" | tr 'a-z' 'A-Z'
7: done
8: --------------------
9: # gawk sample:g5
10: {
11: print $0 |& "to_upper"
12: "to_upper" |& getline hold
13: print hold
14: }
15: --------------------
16: gawk -f g5 < alpha
17: --------------------
18: AAAAAAAAAAA
19: BBBBBBBBBBB
20: CCCCCCCCCCC
21: DDDDDDDDDDD
to_upper封装tr,在g5中,先从alpha中读出小写,如“aaaaaaaaaaa”,重定向输出给协进程to_upper,to_upper处理,转化为大写,然后to_upper输出给标准输出,重定向给getline。