1. AWK基础概念与工作原理
AWK作为Unix/Linux环境下最强大的文本处理工具之一,其设计哲学可以概括为"简单的事情简单做,复杂的事情可能做"。我第一次接触AWK是在处理一个5GB的服务器日志文件时,当时用普通的shell脚本处理效率极低,而AWK仅用一行命令就解决了问题,从此我便深深着迷于这个工具。
1.1 AWK的核心处理模型
AWK将输入数据视为由记录(Record)和字段(Field)组成的结构化表格。默认情况下:
- 每条记录就是一行文本(由RS变量控制)
- 每个字段是该行的文本片段(由FS变量控制)
这个模型看似简单,却蕴含巨大能量。举个例子,当我们需要分析nginx访问日志时:
bash复制awk '{print $1}' access.log | sort | uniq -c | sort -nr
这行命令就能统计出访问量最高的IP地址,其中:
$1表示每行第一个字段(默认空格分隔)- sort和uniq组合实现计数和排序
1.2 AWK程序的执行流程
一个完整的AWK程序遵循BEGIN-主体-END的执行顺序:
bash复制awk 'BEGIN {print "开始分析"}
{sum += $3; count++}
END {print "平均值:", sum/count}' data.txt
实际执行时:
- 先执行BEGIN块(常用于初始化)
- 然后逐行处理输入数据
- 最后执行END块(常用于汇总输出)
经验之谈:在BEGIN块中设置FS(字段分隔符)、OFS(输出分隔符)等变量,可以避免在主体部分重复计算,这是提升AWK脚本性能的小技巧。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. AWK内置变量深度解析
2.1 必须掌握的9个核心变量
| 变量名 | 描述 | 典型应用场景 | 示例 |
|---|---|---|---|
| NR | 当前记录号(行号) | 行号标记 | awk '{print NR, $0}' |
| NF | 当前记录的字段数 | 验证数据完整性 | awk 'NF != 6 {print}' |
| FS | 输入字段分隔符 | 解析CSV文件 | awk 'BEGIN {FS=","} {...}' |
| OFS | 输出字段分隔符 | 格式化输出 | awk 'BEGIN {OFS="\t"} {...}' |
| RS | 输入记录分隔符 | 处理非行式数据 | awk 'BEGIN {RS="\n\n"}' |
| ORS | 输出记录分隔符 | 生成特定格式数据 | awk 'BEGIN {ORS="\r\n"}' |
| FILENAME | 当前输入文件名 | 多文件处理 | awk '{print FILENAME}' |
| ARGC/ARGV | 参数个数/参数数组 | 脚本参数处理 | awk 'BEGIN {print ARGV[1]}' |
| ENVIRON | 环境变量数组 | 获取系统环境 | awk 'BEGIN {print ENVIRON["HOME"]}' |
2.2 变量使用的高级技巧
处理多文件时,FNR与NR的区别至关重要:
bash复制# FNR在每个文件内重置,NR持续累加
awk '{print FILENAME, FNR, NR}' file1 file2
动态修改字段内容后,需要重建$0:
bash复制awk '{$3="new"; $1=$1; print}' file
# $1=$1 强制AWK用OFS重新组合字段
踩坑记录:曾经在处理Windows生成的文件时,因为忘记处理CRLF(\r\n)导致行数统计出错。解决方案是在BEGIN块添加
RS="\r?\n"。
3. 模式匹配与操作组合
3.1 六种模式匹配方式
-
正则匹配:最常用的模式
bash复制awk '/error/ {count++} END {print count}' logfile -
字段关系:精确的字段控制
bash复制awk '$3 > 100 && $5 ~ /success/' transactions.log -
范围模式:处理数据块
bash复制awk '/START/,/END/' data.txt -
BEGIN/END:预处理和后处理
bash复制awk 'BEGIN
