AWK 条件判断与模式匹配

《AWK 条件判断与模式匹配》


🎯 学习目标

  • 掌握 AWK 中的条件判断语法(if、else if、else)
  • 理解如何使用正则表达式进行模式匹配
  • 能够根据字段内容或整行内容筛选日志或数据
  • 在实际场景中应用条件判断处理服务器日志、系统配置文件等
  • 提升脚本灵活性和可维护性,实现自动化分析功能

🔑 核心重点

概念 内容
条件判断 if, else if, else 控制语句流程
比较操作符 ==, !=, <, >, <=, >=
逻辑操作符 &&(与)、||(或)、!(非)
模式匹配 使用 /pattern/ 进行正则匹配;~!~ 判断是否匹配
应用场景 过滤特定状态码的日志、提取错误信息、统计访问来源等

📚 详细讲解


一、条件判断:if、else if、else

在 AWK 中,你可以像其他语言一样使用 ifelse ifelse 控制程序流程。

示例1:根据状态码输出分类信息

awk '{if ($9 == 200) print "成功:", $7; else if ($9 >= 400 && $9 < 500) print "客户端错误:", $7; else print "其他状态:", $9}' access.log

说明:

  • $9 是 Nginx 日志中的 HTTP 状态码
  • 分别判断状态码为 200(成功)、4xx(客户端错误)、其他情况并输出不同信息

示例2:结合 NR 行号判断

awk '{if (NR == 1) print "这是第一行"; else print $0}' sample.txt

✅ 小技巧:NR == 1 可用于跳过表头或处理首行特殊逻辑


二、正则表达式与模式匹配

1. 基本写法:/pattern/

awk '/error/ {print}' /var/log/syslog

说明:打印包含 error 的所有行

2. 字段匹配:使用 ~!~

awk '$7 ~ /\.php$/ {print $7}' access.log

说明:匹配第 7 个字段以 .php 结尾的请求路径

⚠️ 注意:正则表达式要放在斜杠 / 中,或者使用 ~ 显式匹配字符串字段

3. 多条件组合匹配

awk '$9 == 404 && $7 ~ /admin/ {print "404 管理页面未找到: " $7}' access.log

说明:同时满足状态码是 404 且请求路径包含 admin


三、实战案例:分析 Nginx 日志

场景:找出访问 /api/user/login 的 IP 地址

awk '$7 == "/api/user/login" {print $1}' access.log | sort | uniq -c | sort -nr

输出示例:

  5 192.168.1.100
  3 192.168.1.101

说明:

  • $7 是请求路径字段
  • 使用 sort | uniq -c 统计每个 IP 访问次数
  • 最后用 sort -nr 按数字倒序排序

四、实战案例:过滤 Ubuntu 系统日志

场景:找出 /var/log/syslog 中包含 CRONsshd 的日志,并按类型分类输出

awk '/CRON/{type="定时任务"} /sshd/{type="SSH登录"} {print type, $3, $4}' /var/log/syslog

说明:

  • 如果匹配 CRON,设置变量 type 为“定时任务”
  • 如果匹配 sshd,设置变量 type 为“SSH登录”
  • 输出日志类型 + 时间戳部分字段

🧪 测试建议:使用 head -n 100 /var/log/syslog 先测试小范围数据


五、实战案例:分析用户访问频率(IP+时间)

场景:找出每分钟访问超过 10 次的 IP 地址(假设日志格式含时间戳)

awk '{split($4, arr, ":"); key = $1 " " arr[2] ":" arr[3]; count[key]++} END {for (k in count) if (count[k] > 10) print k, count[k]}' access.log

说明:

  • $4 是日志中的时间戳字段,如 [10/May/2025:10:00:01 +0800]
  • 使用 split() 提取小时和分钟部分作为分组键
  • key = $1 " " arr[2] ":" arr[3] 表示 IP + 分钟
  • 最终遍历 count 数组,找出访问次数大于 10 的记录

六、不同 Linux 发行版差异(Ubuntu vs CentOS vs EulerOS)

特性 Ubuntu CentOS EulerOS
默认 awk gawk gawk gawk
日志路径 /var/log/syslog /var/log/messages /var/log/messages
日志格式 ISO 时间较多 传统 syslog 格式 支持 journald 日志
字段顺序 不同服务可能有变化 需注意日志结构 日志结构类似 CentOS

📌 小贴士:

  • 使用 head -n 5 /var/log/syslog 查看日志格式再写脚本
  • CentOS/EulerOS 上查看 /var/log/messages 需要用 sudo

七、高级技巧:BEGIN 与 END 的妙用

1. 初始化统计变量

awk 'BEGIN{total=0} $9 == 200 {total++} END{print "总共有", total, "次 200 请求"}' access.log

说明:

  • BEGIN{} 在开始前执行一次
  • END{} 在处理完所有行后执行
  • 实现统计功能

2. 输出标题与表格化输出

awk 'BEGIN{print "IP地址\t访问次数"} $9 == 200 {count[$1]++} END{for (ip in count) print ip "\t" count[ip]}' access.log

输出示例:

IP地址	访问次数
192.168.1.100	150
192.168.1.101	89

八、调试技巧

  • 使用 print $0 打印原始行,确认是否符合预期
  • 使用 print NF 查看字段数量是否正确
  • 使用 print substr($0, 1, 50) 查看前几个字符,辅助定位字段偏移
  • 使用 head -n 5 file | awk '...' 测试脚本前先小范围验证

✅ 总结

掌握 条件判断模式匹配 是编写复杂 AWK 脚本的关键。通过这些功能,你可以在日志分析、系统监控、数据清洗等方面实现自动化处理。

在 Ubuntu 环境下,结合 grepsortuniq 等命令,可以构建强大的日志分析流水线,帮助你快速发现异常行为、统计访问趋势、识别高频用户等。

继续练习真实日志文件,将大大提升你在 Linux 文本处理方面的实战能力!🚀

posted @ 2025-06-22 22:36  红尘过客2022  阅读(223)  评论(0)    收藏  举报