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。

原文地址:https://www.cnblogs.com/YFYkuner/p/2676038.html