✸ ✸ ✸
awk 匹配的两种模式
awk 是 Linux 文本处理三剑客之一(grep、sed、awk)。在数据过滤场景中,经常需要区分"模糊匹配"和"精确匹配",两者的行为差异很大。
模糊匹配(正则匹配)
使用 // 或 ~ 运算符,只要行中包含匹配内容就命中:
$ cat data.txt
apple
application
pineapple
banana
app
# 模糊匹配:包含 "app" 的行全部命中
$ awk '/app/' data.txt
apple
application
pineapple
app
# 等价写法:$0 ~ /pattern/
$ awk '$0 ~ /app/' data.txt
apple
application
pineapple
app
这里 /app/ 是正则表达式,匹配行中任意位置出现的 "app"。
精确匹配(字符串相等)
使用 == 运算符,要求完全相等:
# 精确匹配:只有完全等于 "app" 的行
$ awk '$0 == "app"' data.txt
app
# 对比:精确匹配 "apple"
$ awk '$0 == "apple"' data.txt
apple
匹配流程对比
输入行: "application"
模糊匹配 /app/:
"application" 中包含 "app"? --> 是 --> 输出该行
精确匹配 == "app":
"application" 完全等于 "app"? --> 否 --> 跳过
按字段匹配
实际工作中,数据通常是多列的,需要对特定字段做匹配:
$ cat users.txt
1001 zhangsan Beijing
1002 lisi Shanghai
1003 zhangwei Beijing
1004 wangwu Guangzhou
# 模糊匹配第2列包含 "zhang"
$ awk '$2 ~ /zhang/' users.txt
1001 zhangsan Beijing
1003 zhangwei Beijing
# 精确匹配第3列等于 "Beijing"
$ awk '$3 == "Beijing"' users.txt
1001 zhangsan Beijing
1003 zhangwei Beijing
# 精确匹配第2列等于 "lisi"
$ awk '$2 == "lisi"' users.txt
1002 lisi Shanghai
反向匹配(取反)
# 模糊匹配取反:不包含 "app" 的行
$ awk '!/app/' data.txt
banana
# 精确匹配取反:不等于 "app" 的行
$ awk '$0 != "app"' data.txt
apple
application
pineapple
banana
# 字段取反:第3列不是 "Beijing"
$ awk '$3 != "Beijing"' users.txt
1002 lisi Shanghai
1004 wangwu Guangzhou
正则匹配进阶
# 匹配以 "app" 开头的行
$ awk '/^app/' data.txt
apple
application
app
# 匹配以 "le" 结尾的行
$ awk '/le$/' data.txt
apple
pineapple
# 匹配数字
$ echo -e "abc\n123\na1b" | awk '/^[0-9]+$/'
123
# 匹配 IP 地址格式
$ awk '/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/' access.log
实战场景
场景1:从日志中筛选特定状态码
# Nginx access.log 格式:IP - - [time] "request" status size
# 精确匹配状态码 500
awk '$9 == "500"' access.log
# 模糊匹配所有 5xx 错误
awk '$9 ~ /^5/' access.log
# 统计各状态码出现次数
awk '{print $9}' access.log | sort | uniq -c | sort -rn
场景2:从 /etc/passwd 筛选用户
# 精确匹配用户名
awk -F: '$1 == "root"' /etc/passwd
# 模糊匹配 shell 包含 "bash" 的用户
awk -F: '$7 ~ /bash/' /etc/passwd
# UID 大于 1000 的普通用户
awk -F: '$3 >= 1000' /etc/passwd
场景3:CSV 数据过滤
# 精确匹配部门为 "IT" 的员工
awk -F',' '$3 == "IT"' employees.csv
# 模糊匹配名字包含 "wang" 的员工(忽略大小写用 tolower)
awk -F',' 'tolower($2) ~ /wang/' employees.csv
匹配方式速查
| 需求 | 语法 | 说明 |
|---|---|---|
| 整行包含 pattern | /pattern/ | 模糊匹配 |
| 字段包含 pattern | $N ~ /pattern/ | 字段模糊匹配 |
| 整行等于 string | $0 == "string" | 精确匹配 |
| 字段等于 string | $N == "string" | 字段精确匹配 |
| 不包含 pattern | !/pattern/ | 模糊取反 |
| 字段不等于 string | $N != "string" | 精确取反 |
| 以 pattern 开头 | /^pattern/ | 正则锚定 |
| 以 pattern 结尾 | /pattern$/ | 正则锚定 |
总结
记住一个核心区别:~ 和 // 是"包含"关系(模糊),== 是"等于"关系(精确)。日志分析、数据过滤时选对匹配方式,能避免很多误筛的坑。
✸ ✸ ✸
📜 版权声明
本文作者:王梓 | 原文链接:https://www.bthlt.com/note/6278277-Linuxawk精确匹配和模糊匹配
出处:葫芦的运维日志 | 转载请注明出处并保留原文链接


📜 留言板
留言提交后需管理员审核通过才会显示