侧边栏壁纸
博主头像
张种恩的技术小栈博主等级

行动起来,活在当下

  • 累计撰写 748 篇文章
  • 累计创建 65 个标签
  • 累计收到 39 条评论

目 录CONTENT

文章目录

AWK(4)之使用模式

zze
zze
2019-12-25 / 0 评论 / 0 点赞 / 711 阅读 / 2736 字

不定期更新相关视频,抖音点击左上角加号后扫一扫右方侧边栏二维码关注我~正在更新《Shell其实很简单》系列

本部分内容参考自《Linux命令行与shell脚本编程大全 第3版》。

gawk 程序支持多种类型的匹配模式来过滤数据记录,这一点跟 sed 编辑器大同小异。已经介绍了两种特殊的模式在实践中的应用, BEGINEND 关键字是用来在读取数据流之前或之后执行命令的特殊模式。类似地,你可以创建其他模式在数据流中出现匹配数据时执行一些命令。

正则表达式

可以用基础正则表达式(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 匹配了一条记录。

0
AWK

评论区