AWK 控制流语句

《AWK 控制流语句》


🎯 学习目标

  • 掌握 AWK 中的 条件判断(if、else if、else)
  • 理解 循环结构(for、while、do...while)
  • 能在实际日志分析中使用控制流进行复杂逻辑处理
  • 结合 Ubuntu 系统日志、Nginx 日志等真实数据编写脚本
  • 提升脚本灵活性与可读性,为自动化运维打基础

🔑 核心重点

类型 内容
条件判断 if, else if, else
循环控制 for, while, do...while
跳转语句 break, continue, next, exit
应用场景 日志过滤、状态码统计、用户行为分析、系统资源监控
注意事项 AWK 的数组是无序的;不同发行版字段位置可能不同

📚 详细讲解


一、条件判断语句:ifelse ifelse

1. 基本语法

awk '{if (条件) {动作} else if (条件) {动作} else {动作}}'

2. 示例:根据 HTTP 状态码分类输出

awk '
{
    status = $9
    if (status == 200)
        print "成功:", $7
    else if (status >= 400 && status < 500)
        print "客户端错误:", $7
    else if (status >= 500)
        print "服务器错误:", $7
}' access.log

📌 输出示例:

成功: /index.html
客户端错误: /login.php
服务器错误: /api/user

✅ 小技巧:

  • 可用于识别异常访问路径或高频错误请求
  • 搭配 sort | uniq -c 统计错误次数更直观

二、循环语句:forwhiledo...while

1. for 循环:遍历数组最常用

awk 'BEGIN {
    for (i=1; i<=5; i++)
        print i
}'

输出:

1
2
3
4
5

2. 实战:遍历 /etc/passwd 用户并编号输出

awk -F: 'NR==FNR {count++}
END {
    for (i=1; i<=count; i++)
        print "用户" i ": "用户名[i]
}' /etc/passwd /etc/passwd

⚠️ 注意:这个例子只是为了演示 for 使用方式,实际中通常用 NR 直接处理。


3. while 循环:适合不确定循环次数的情况

awk 'BEGIN {
    i = 1
    while (i <= 5) {
        print i
        i++
    }
}'

输出:

1
2
3
4
5

4. do...while 循环:至少执行一次

awk 'BEGIN {
    i = 1
    do {
        print i
        i++
    } while (i <= 5)
}'

输出同上


三、跳转语句:breakcontinuenextexit

1. break:跳出当前循环

awk 'BEGIN {
    for (i=1; i<=10; i++) {
        if (i > 5) break
        print i
    }
}'

输出:

1
2
3
4
5

2. continue:跳过本次循环

awk 'BEGIN {
    for (i=1; i<=5; i++) {
        if (i == 3) continue
        print i
    }
}'

输出:

1
2
4
5

3. next:跳过当前记录,继续下一行

awk '$9 != 200 {next} {print $7}' access.log

说明:

  • 如果状态码不是 200,跳过该行
  • 否则输出请求路径 $7

4. exit:提前退出脚本

awk '/error/ {print "发现错误"; exit}' /var/log/syslog

说明:

  • 一旦匹配到 error 字样,立即输出并退出

四、实战案例:结合 Nginx 日志做高级筛选

场景:找出所有状态码为 4xx 或 5xx 的请求,并按 IP 分类统计

awk '
$9 >= 400 && $9 < 600 {
    error_ip[$1]++
}
END {
    print "错误来源IP统计:"
    for (ip in error_ip)
        print ip, error_ip[ip]
}' access.log

输出示例:

错误来源IP统计:
192.168.1.100 12
192.168.1.102 5

五、实战案例:提取系统用户并排序输出(Ubuntu vs CentOS vs EulerOS)

场景:从 /etc/passwd 中提取 UID >= 1000 的普通用户并按字母排序

awk -F: '$3 >= 1000 {user[$1]=$3} END {
    PROCINFO["sorted_in"] = "@ind_str_asc"
    for (u in user)
        print u, user[u]
}' /etc/passwd

输出示例:

alice 1001
bob   1002
ubuntu 1000

📌 说明:

  • PROCINFO["sorted_in"] 是 GAWK 特有功能,用于控制数组遍历顺序
  • "@ind_str_asc" 表示按键名(用户名)按字符串升序排列

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

功能 Ubuntu CentOS EulerOS
默认 awk gawk gawk gawk
支持 PROCINFO["sorted_in"] ✅(gawk 4.0+)
/etc/passwd 字段结构 一致 一致 一致
日志文件位置 /var/log/syslog /var/log/messages /var/log/messages
权限要求 查看 /var/log/* 需要 sudo 同左 同左

📌 小贴士:

  • 在 CentOS/EulerOS 上查看 /var/log/messages 需要管理员权限,建议使用 sudo awk ...
  • 不同系统的日志格式会影响字段提取逻辑,请先观察几行日志结构再写脚本

七、调试与优化建议

技巧 说明
print $0 打印原始行内容,确认是否符合预期
print NF 查看字段数量是否正确
print substr($0, 1, 50) 查看前几个字符,辅助定位字段偏移
`head -n 5 file awk '...'`
BEGIN{FS=","} 设置合适的字段分隔符提升可读性

✅ 总结

掌握 AWK 的控制流语句(条件判断、循环、跳转),是编写复杂脚本的关键一步。通过这些结构,你可以在日志分析、系统监控、用户行为追踪等方面实现灵活而强大的自动化处理。

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

继续练习真实日志文件,你会越来越熟练地运用这些控制流语句,成为一名真正的 Linux 文本处理高手!🚀🔥

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