AWK 文件处理
《AWK 文件处理》
🎯 学习目标
- 掌握 AWK 对多个文件的顺序读取、合并处理技巧
- 理解
FILENAME、FNR、NR的区别与应用场景 - 能够编写脚本实现日志合并、字段提取、跨文件匹配等复杂任务
- 结合 Ubuntu、CentOS、EulerOS 实际环境,提升文本处理能力
- 了解不同 Linux 发行版对 AWK 处理方式的影响和注意事项
🔑 核心重点
| 概念 | 内容 |
|---|---|
| 读取多文件 | 支持同时传入多个文件名作为参数 |
| 内置变量 | FILENAME, FNR, NR, ARGC, ARGV |
| 逐行处理机制 | 每个文件独立计数(FNR),整体统一计数(NR) |
| 实战应用 | 日志合并分析、系统配置对比、用户访问行为追踪 |
| 注意事项 | 不同发行版日志路径差异;权限问题影响读取;awk/gawk 兼容性 |
📚 详细讲解
一、AWK 是如何读取文件的?
AWK 可以像 cat 或 grep 一样直接读取一个或多个文件内容,并按行进行处理。
示例:读取单个文件并输出每行内容
awk '{print FILENAME, FNR, $0}' /etc/passwd
📌 输出示例:
/etc/passwd 1 root:x:0:0:root:/root:/bin/bash
/etc/passwd 2 daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
✅ 解释:
FILENAME:当前正在处理的文件名FNR:当前文件内的行号(File Number of Record)NR:全局行号(Number of Record)
二、一次处理多个文件
AWK 支持一次性传入多个文件,它会自动依次读取每个文件。
示例:处理两个日志文件
awk '{print FILENAME, FNR, $0}' /var/log/syslog /var/log/auth.log
📌 输出示例:
/var/log/syslog 1 Jun 22 10:00:00 ...
/var/log/syslog 2 Jun 22 10:05:00 ...
/var/log/auth.log 1 Jun 22 10:00:00 sshd[...]
...
三、实战案例:合并多个日志文件并添加来源标识
场景:将 /var/log/syslog 和 /var/log/auth.log 合并成一份日志,并标注来自哪个文件
awk '
{
if (FILENAME == "/var/log/syslog")
source = "syslog"
else if (FILENAME == "/var/log/auth.log")
source = "auth"
print "[" source "]", $0
}' /var/log/syslog /var/log/auth.log > merged.log
📌 输出到 merged.log 示例:
[syslog] Jun 22 10:00:00 ...
[auth] Jun 22 10:00:00 sshd[...]
✅ 应用价值:
- 集中化日志管理
- 安全审计时区分日志类型
- 自动化报告生成工具基础
四、实战案例:跨文件查找匹配记录(如 IP 登录日志 + 用户列表)
场景:从 /etc/passwd 中提取用户名,然后在 /var/log/auth.log 中查找该用户的登录记录
awk -F: 'NR == FNR {
# 第一个文件是 /etc/passwd,保存所有用户名
users[$1] = 1
next
}
$1 in users {
# 第二个文件是 auth.log,只打印匹配的行
print $0
}' /etc/passwd /var/log/auth.log
📌 输出示例:
ubuntu sshd[1234]: Accepted password for ubuntu from 192.168.1.100 port 22
✅ 技巧说明:
NR == FNR表示正在读取第一个文件(/etc/passwd)next表示跳过后续处理,继续下一行- 使用数组
users[]来快速判断是否存在
五、实战案例:统计每个文件中的总行数
场景:查看多个日志文件各有多少行
awk 'END {count[FILENAME] = FNR}
END {
for (file in count)
print file, ":", count[file], "行"
}' /var/log/syslog /var/log/auth.log
📌 输出示例:
/var/log/syslog : 1500 行
/var/log/auth.log : 300 行
六、实战案例:根据文件名动态设置分隔符
场景:处理 CSV 和 TSV 文件时使用不同的字段分隔符
awk 'BEGIN {
OFS = "\t" # 设置输出字段分隔符为制表符
}
FILENAME ~ /\.csv$/ {
FS = "," # 如果是 .csv 文件,用逗号分隔
}
FILENAME ~ /\.tsv$/ {
FS = "\t" # 如果是 .tsv 文件,用制表符分隔
}
{
print FILENAME, $1, $2, $3
}' data.csv data.tsv
📌 输出示例:
data.csv Alice 25 Engineer
data.tsv Bob 30 Developer
七、不同 Linux 发行版注意事项(Ubuntu vs CentOS vs EulerOS)
| 功能 | Ubuntu | CentOS | EulerOS |
|---|---|---|---|
| 默认 awk | gawk | gawk | gawk |
/etc/passwd 结构 |
标准 | 标准 | 标准 |
| 日志文件位置 | /var/log/syslog, /var/log/auth.log |
/var/log/messages, /var/log/secure |
同 CentOS |
| 查看日志权限 | 一般需 sudo | 需 sudo | 需 sudo |
| 多文件处理支持 | ✅ | ✅ | ✅ |
📌 小贴士:
- 在 CentOS/EulerOS 上查看
/var/log/secure需要管理员权限,建议使用sudo awk ... - 不同系统的日志格式会影响字段提取逻辑,请先观察几行日志结构再写脚本
八、调试与优化建议
| 技巧 | 说明 |
|---|---|
print FILENAME, FNR, $0 |
快速确认文件是否正确读取 |
| `head -n 5 file | awk '...'` |
BEGIN{FS=","} |
设置合适的字段分隔符提升可读性 |
FNR == 1 {print "开始处理:" FILENAME} |
打印文件切换信息便于调试 |
delete array |
清空数组释放内存,适用于大文件处理 |
✅ 总结
AWK 强大的文件处理能力使其成为日志分析、系统监控、自动化运维的利器。通过掌握以下技能,你可以在 Ubuntu、CentOS、EulerOS 等不同 Linux 系统上灵活地完成复杂的数据处理任务:
- 一次处理多个文件
- 区分文件来源并动态设置处理逻辑
- 提取关键字段并格式化输出
- 实现跨文件数据关联与匹配
- 构建自动化日志分析流程
结合 grep、sort、uniq 等命令,你可以轻松构建出完整的日志处理流水线。
继续练习真实日志文件,你会越来越熟练地运用这些文件处理技巧,成为一名真正的 Linux 文本处理高手!🚀🔥

浙公网安备 33010602011771号