本部分内容参考自《Linux命令行与shell脚本编程大全 第3版》。
gawk 程序支持多种类型的匹配模式来过滤数据记录,这一点跟 sed 编辑器大同小异。已经介绍了两种特殊的模式在实践中的应用, BEGIN
和 END
关键字是用来在读取数据流之前或之后执行命令的特殊模式。类似地,你可以创建其他模式在数据流中出现匹配数据时执行一些命令。
正则表达式
可以用基础正则表达式(BRE)或扩展正则表达式(ERE)来选择程序脚本作用在数据流中的哪些行上。
在使用正则表达式时,正则表达式必须出现在它要控制的程序脚本的左花括号前。
$ cat test3.txt
data11,data12,data13,data14,data15
data21,data22,data23,data24,data25
data31,data32,data33,data34,data35
$ gawk 'BEGIN{FS=","} /11/{print $1}' test3.txt
data11
正则表达式 /11/
匹配了数据字段中含有字符串 11
的记录。 gawk 程序会用正则表达式对记录中所有的数据字段进行匹配,包括字段分隔符。
匹配操作符
匹配操作符(matching operator)允许将正则表达式限定在记录中的特定数据字段。匹配操作符是波浪线(~
)。可以指定匹配操作符、数据字段变量以及要匹配的正则表达式。
$1 ~ /^data/
$1
变量代表记录中的第一个数据字段。这个表达式会过滤出第一个字段以文本 data
开头的所有记录。下面是在 gawk 程序脚本中使用匹配操作符的例子。
$ gawk 'BEGIN{FS=","} $2 ~ /^data2/{print $0}' test3.txt
data21,data22,data23,data24,data25
匹配操作符会用正则表达式 /^data2/
来比较第二个数据字段,该正则表达式指明字符串要以文本 data2
开头。
这可是件强大的工具, gawk 程序脚本中经常用它在数据文件中搜索特定的数据元素。
$ gawk -F: '$1 ~ /mysql/{print $1,$NF}' /etc/passwd
mysql /bin/bash
这个例子会在第一个数据字段中查找文本 mysql
。如果在记录中找到了这个模式,它会打印该记录的第一个和最后一个数据字段值。
你也可以用 !
符号来排除正则表达式的匹配。
$1 !~ /expression/
如果记录中没有找到匹配正则表达式的文本,程序输出所有文本行。
$ gawk -F: '$1 !~ /mysql/{print $1,$NF}' /etc/passwd
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
...
在这个例子中, gawk 程序脚本会打印 /etc/passwd
文件中与用户名 mysql
不匹配的用户名和默认 shell。
数学表达式
除了正则表达式,你也可以在匹配模式中用数学表达式。这个功能在匹配数据字段中的数字值时非常方便。举个例子,如果你想显示所有属于 root 用户组(组 ID 为 0)的系统用户,可以用这个脚本。
$ gawk -F: '$4 == 0{print $1}' /etc/passwd
root
sync
shutdown
halt
operator
这段脚本会查看第四个数据字段含有值 0 的记录。在这个 Linux 系统中,有五个用户账户属于 root 用户组。
可以使用任何常见的数学比较表达式。
x == y
:值x
等于y
;x <= y
:值x
小于等于y
;x < y
:值x
小于y
;x >= y
:值x
大于等于y
;x > y
:值x
大于y
;
也可以对文本数据使用表达式,但必须小心。跟正则表达式不同,表达式必须完全匹配。数据必须跟模式严格匹配。
$ gawk -F, '$1 == "data"{print $1}' test3.txt
$ gawk -F, '$1 == "data11"{print $1}' test3.txt
data11
第一个测试没有匹配任何记录,因为第一个数据字段的值不在任何记录中。第二个测试用值 data11
匹配了一条记录。
评论区