Windows上GAWK的使用(三)

来源:互联网 发布:流量使用情况软件 编辑:程序博客网 时间:2024/05/06 19:38

9. 匹配操作符(~)

用来在记录或者域内匹配正则表达式。如gawk.exe "$1 ~/^root/" test.txt将显示test文件第一列中以root开头的行。

10. 比较表达式

conditional expression_r1 ? expression_r2: expression_r3,例如:gawk.exe "{max = {$1 > $3} ? $1: $3: print max}" test。如果第一个域大于第三个域,$1就赋值给max,否则$3就赋值给max。

gawk.exe "$1 + $2 < 100" test。如果第一和第二个域相加大于100,则打印这些行。

gawk.exe "$1 > 5 && $2 < 10" test,如果第一个域大于5,并且第二个域小于10,则打印这些行。

11. 范围模板

范围模板匹配从第一个模板的第一次出现到第二个模板的第一次出现之间所有行。如果有一个模板没出现,则匹配到开头或末尾。如gawk.exe "/root/,/mysql/" test将显示root第一次出现到mysql第一次出现之间的所有行。

13. 几个实例

*

gawk.exe "/^(no|so)/" test.txt-----打印所有以模式no或so开头的行。

*

gawk.exe "/^[ns]/{print $1}" test.txt -----如果记录以n或s开头,就打印这个记录。

*

gawk.exe "$1 ~/[0-9][0-9]$/(print $1)" test.txt -----如果第一个域以两个数字结束就打印这个记录。

*

gawk.exe "$1 == 100 || $2 < 50" test.txt -----如果第一个或等于100或者第二个域小于50,则打印该行。

*

gawk.exe "$1 != 10" test.txt -----如果第一个域不等于10就打印该行。

*

gawk.exe "/test/{print $1 + 10}" test.txt -----如果记录包含正则表达式test,则第一个域加10并打印出来。

*

gawk.exe "{print ($1 > 5 ? "ok "$1: "error"$1)}" test.txt -----如果第一个域大于5则打印问号后面的表达式值,否则打印冒号后面的表达式值。

*

gawk.exe "/^root/,/^mysql/" test.txt ----打印以正则表达式root开头的记录到以正则表达式mysql开头的记录范围内的所有记录。如果找到一个新的正则表达式root开头的记录,则继续打印直到下一个以正则表达式mysql开头的记录为止,或到文件末尾。

14.gawk编程

14.1. 变量

*

在gawk中,变量不需要定义就可以直接使用,变量类型可以是数字或字符串。

*

赋值格式:Variable = expression_r,如gawk.exe "$1 ~/test/{count = $2 + $3; print count}" test.txt,上式的作用是,gawk先扫描第一个域,一旦test匹配,就把第二个域的值加上第三个域的值,并把结果赋值给变量count,最后打印出来。

*

gawk 可以在命令行中给变量赋值,然后将这个变量传输给gawk脚本。如gawk.exe –F”:” -f awkscript month=4 year=2004 test,上式的month和year都是自定义变量,分别被赋值为4和2004。在awk脚本中,这些变量使用起来就象是在脚本中建立的一样。注意,如果参数前面出现test,那么在BEGIN语句中的变量就不能被使用。

*

域变量也可被赋值和修改,如gawk.exe "{$2 = 100 + $1; print }" test.txt,上式表示,如果第二个域不存在,gawk将计算表达式100加$1的值,并将其赋值给$2,如果第二个域存在,则用表达式的值覆盖$2原来的值。再例如:gawk.exe "$1 == "root"{$1 ="test";print}" test.txt,如果第一个域的值是“root”,则把它赋值为“test”,注意,字符串一定要用双引号。

*

内建变量的使用。变量列表在前面已列出,现在举个例子说明一下。gawk.exe -F: "{IGNORECASE=1; $1 == "MARY"{print NR,$1,$2,$NF}"test,把IGNORECASE设为1代表忽略大小写,打印第一个域是mary的记录数、第一个域、第二个域和最后一个域。

14.2. BEGIN模块

BEGIN 模块后紧跟着动作块,这个动作块在awk处理任何输入文件之前执行。所以它可以在没有任何输入的情况下进行测试。它通常用来改变内建变量的值,如OFS, RS和FS等,以及打印标题。如:gawk.exe "BEGIN{FS=":"; OFS="\t"; ORS="\n\n"}{print $1,$2,$3} test.txt。上式表示,在处理输入文件以前,域分隔符(FS)被设为冒号,输出文件分隔符(OFS)被设置为制表符,输出记录分隔符(ORS)被设置为两个换行符。gawk.exe "BEGIN{print "TITLE TEST"}只打印标题。

14.3. END模块

END不匹配任何的输入文件,但是执行动作块中的所有动作,它在整个输入文件处理完成后被执行。如gawk.exe "END{print "The number of records is" NR}"  test.txt,上式将打印所有被处理的记录数。

14.4. 重定向和管道

*

awk 可使用shell的重定向符进行重定向输出,如:gawk.exe "$1 = 100 {print $1 > "output_file" }"  test.txt。上式表示如果第一个域的值等于100,则把它输出到output_file中。也可以用>>来重定向输出,但不清空文件,只做追加操作。

*

输出重定向需用到getline函数。getline从标准输入、管道或者当前正在处理的文件之外的其他输入文件获得输入。它负责从输入获得下一行的内容,并给NF,NR和FNR等内建变量赋值。如果得到一条记录,getline函数返回1,如果到达文件的末尾就返回0,如果出现错误,例如打开文件失败,就返回-1。如:

gawk.exe "BEGIN{ "date" | getline d; print d}"  test.txt。执行linux的date命令,并通过管道输出给getline,然后再把输出赋值给自定义变量d,并打印它。

gawk.exe "BEGIN{"date" | getline d; split(d,mon); print mon[2]}" test。执行shell的date命令,并通过管道输出给getline,然后getline从管道中读取并将输入赋值给d,split函数把变量d转化成数组mon,然后打印数组mon的第二个元素。

gawk.exe "BEGIN{while( "ls" | getline) print}",命令ls的输出传递给geline作为输入,循环使getline从ls的输出中读取一行,并把它打印到屏幕。这里没有输入文件,因为 BEGIN块在打开输入文件前执行,所以可以忽略输入文件。

gawk.exe "BEGIN{printf "What is your name?"; getline name < "/dev/tty" } $1 ~name {print "Found" name on line ", NR "."} END{print "See you," name "."} test.txt。在屏幕上打印”What is your name?",并等待用户应答。当一行输入完毕后,getline函数从终端接收该行输入,并把它储存在自定义变量name中。如果第一个域匹配变量 name的值,print函数就被执行,END块打印See you和name的值。

gawk.exe "BEGIN{while (getline < "/etc/passwd" > 0) lc++; print lc}"。awk将逐行读取文件/etc/passwd的内容,在到达文件末尾前,计数器lc一直增加,当到末尾时,打印lc的值。注意,如果文件不存在,getline返回-1,如果到达文件的末尾就返回0,如果读到一行,就返回1,所以命令 while (getline < "/etc/passwd")在文件不存在的情况下将陷入无限循环,因为返回-1表示逻辑真。

*

可以在awk中打开一个管道,且同一时刻只能有一个管道存在。通过close()可关闭管道。如:gawk.exe "{print $1, $2 | "sort" }" test END {close("sort")}。awd把print语句的输出通过管道作为linux命令sort的输入,END块执行关闭管道操作。

*

system函数可以在awk中执行linux的命令。如:gawk.exe "BEGIN{system("clear")"。

*

fflush函数用以刷新输出缓冲区,如果没有参数,就刷新标准输出的缓冲区,如果以空字符串为参数,如fflush(""),则刷新所有文件和管道的输出缓冲区。

 

原创粉丝点击