AWK 字段与记录

《AWK 字段与记录》


🎯 学习目标

  • 理解 AWK 中字段(Field)和记录(Record)的基本概念
  • 掌握如何使用 $ 符号访问字段,以及 NFNRFSRS 等内置变量
  • 能够处理多行文本数据并进行结构化分析
  • 掌握如何自定义输入分隔符来解析不同格式的日志或文件
  • 通过实际案例理解在 Ubuntu 系统日志分析、Nginx 日志提取等场景中的应用

🔑 核心重点

概念 内容
字段 使用 $1, $2, ..., $NF 来表示当前记录的各个字段
记录 默认以换行为分隔符的一行文本,可通过 RS 修改
内置变量 NF:字段数量;NR:记录编号;FS:字段分隔符;OFS:输出字段分隔符;RS:记录分隔符;ORS:输出记录分隔符
常用用法 提取特定字段、统计字段数、按条件筛选记录、格式化输出
典型应用场景 分析 Nginx 日志、系统日志 /var/log/syslog、CSV 文件解析、进程信息提取等

📚 详细讲解

一、字段 Field 的基本操作

1. 访问字段

在 AWK 中,每一行被视为一个“记录”,而记录由多个“字段”组成,默认字段之间是空格或 Tab 分隔。

echo "hello world awk" | awk '{print $1, $3}'

输出:

hello awk
  • $0 表示整行内容
  • $1 表示第一个字段
  • $2 表示第二个字段
  • $NF 表示最后一个字段(NF 是 Number of Fields)

2. 示例:提取 /etc/passwd 用户名和 Shell

awk -F: '{print "用户名:", $1, "Shell:", $7}' /etc/passwd

说明:

  • -F: 设置字段分隔符为冒号 :,因为 /etc/passwd 是冒号分隔的
  • 输出每个用户的用户名和登录 Shell

输出片段:

用户名: root Shell: /bin/bash
用户名: daemon Shell: /usr/sbin/nologin
...

二、记录 Record 的理解与控制

1. 默认记录分隔符

默认情况下,每行是一条记录。你可以通过 NR 获取当前记录的序号。

awk '{print NR, $0}' sample.txt

假设 sample.txt 内容如下:

apple banana
orange grape

输出:

1 apple banana
2 orange grape

2. 自定义记录分隔符 RS

有时你想将多个行为一组处理,比如日志中每段日志由空行分隔。

例如:

Log entry 1 line 1
Log entry 1 line 2

Log entry 2 line 1
Log entry 2 line 2

设置 RS="" 表示以空行作为记录分隔符:

awk 'BEGIN{RS=""} {print "第"NR"段日志:\n" $0 "\n"}' log.txt

输出:

第1段日志:
Log entry 1 line 1
Log entry 1 line 2

第2段日志:
Log entry 2 line 1
Log entry 2 line 2

三、字段分隔符 FS 与 OFS

1. 输入字段分隔符 FS

默认是空白字符(空格或 Tab),可以通过 -FBEGIN{FS="..."} 设置。

例如 CSV 文件逗号分隔:

awk -F, '{print $1, $3}' data.csv

2. 输出字段分隔符 OFS

用于控制输出时字段之间的连接符号,默认是空格。

awk 'BEGIN{FS=","; OFS=" => "} {print $1, $3}' data.csv

输出示例:

name => age
Alice => 30
Bob => 25

四、实战案例:解析 Nginx 日志

假设 Nginx 日志格式如下:

192.168.1.1 - - [10/May/2025:10:00:01 +0800] "GET /index.html HTTP/1.1" 200 612 "-" "Mozilla/5.0 ..."

我们可以用 AWK 抽取 IP 地址、请求路径、状态码:

awk '{print "IP地址:", $1, "请求路径:", $7, "状态码:", $9}' access.log

输出示例:

IP地址: 192.168.1.1 请求路径: /index.html 状态码: 200

⚠️ 注意:字段顺序取决于日志格式,不同系统日志可能字段位置不一致,需根据实际情况调整 $n


五、实战案例:分析系统日志 /var/log/syslog

Ubuntu 系统日志通常位于 /var/log/syslog,我们想找出所有包含 CRON 的行,并提取时间戳和信息:

awk '/CRON/{print "时间戳:", $1, $2, $3, "信息:", substr($0, index($0,$4)) }' /var/log/syslog

解释:

  • /CRON/ 匹配包含关键词的行
  • substr($0, index($0,$4)) 从第四个字段开始截取整行内容,避免手动拼接

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

特性 Ubuntu CentOS EulerOS
默认 shell bash bash bash
日志路径 /var/log/syslog /var/log/messages /var/log/messages
日志格式 ISO 时间格式较多 传统 syslog 格式 支持 systemd journal
AWK 实现 gawk(GNU AWK) gawk gawk
默认字段分隔符 空白 空白 空白

📌 小贴士:

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

七、高级技巧:字段合并与字符串处理

1. 合并多个字段

awk '{print $1 " " $2}' file.txt

2. 截取部分字段

awk '{print substr($7, 1, 5)}' file.txt   # 取第7个字段前5个字符

3. 使用 split() 函数分割字段

awk '{split($7, arr, "/"); print arr[3]}' file.txt

例如字段是 /home/user/file.txt,则 arr[3]user


八、调试技巧

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

✅ 总结

AWK 是 Linux 文本处理的利器,尤其适合结构化文本(如日志、CSV、配置文件)的快速提取与分析。掌握字段和记录的操作,可以大幅提升你对服务器日志、性能数据、用户行为等信息的洞察力。

在 Ubuntu 系统下,结合 grepsortuniq 等命令,可以构建强大的日志分析流水线。


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