AWK 初级学习手册(修订版)
一、认识 AWK
- 什么是 AWK
- 一款强大的文本处理工具,特别适合分析结构化文本(如日志、表格数据等)
- 名称来源于三位开发者:Alfred Aho、Peter Weinberger、Brian Kernighan
- 核心能力:按行读取、按字段分割、支持条件判断和计算
- 安装与验证
- 检查是否预装:
awk --version
(Linux 通常自带) - 安装命令:Ubuntu/Debian 用
apt install gawk
,CentOS 用yum install gawk
- 查看帮助:
awk -h
或awk --help
(获取完整选项说明) - 入门测试:
awk 'BEGIN {print "Hello AWK"}'
(输出欢迎语)
二、AWK 基本语法与选项
- 核心用法格式
# 方式1:直接指定处理程序
awk [选项] '处理程序' 文件名...
# 方式2:从文件读取处理程序
awk [选项] -f 程序文件.awk 文件名...
- 常用选项说明(基于 awk -h 输出)
选项 | 长选项 | 说明 |
---|---|---|
-f progfile | --file=progfile | 从文件中读取 AWK 程序 |
-F fs | --field-separator=fs | 设置字段分隔符(替代默认空格或制表符) |
-v var=val | --assign=var=val | 在 AWK 程序开始前设置变量值 |
-e 'program' | --source='program' | 直接提供 AWK 程序代码(可多次使用) |
-h | --help | 显示帮助信息 |
-V | --version | 显示版本信息 |
-i includefile | --include=includefile | 包含其他 AWK 文件(GNU 扩展) |
-l library | --load=library | 加载扩展库(GNU 扩展) |
-M | --bignum | 使用任意精度算术(GNU 扩展) |
-P | --posix | 启用 POSIX 兼容模式 |
-r | --re-interval | 允许正则表达式中的区间操作符(GNU 扩展) |
-S | --sandbox | 沙盒模式,禁止系统调用(安全增强) |
-d[file] | --dump-variables[=file] | 将所有变量及其值写入文件(调试用途) |
-D[file] | --debug[=file] | 启动调试器(GNU 扩展) |
-o[file] | --pretty-print[=file] | 格式化打印 AWK 程序源码(GNU 扩展) |
- 示例:选项使用
# 使用 -v 设置变量
awk -v threshold=50 '$2 > threshold {print $1}' data.txt
# 多段程序组合(使用 -e)
awk -e 'BEGIN {print "Start"}' -e '{print NR, $0}' file.txt
# 包含外部 AWK 文件
awk -i mathlib.awk '{print sqrt($1)}' numbers.txt
三、行与字段处理
- 行处理基础
- 逐行读取:AWK 默认按行处理文件
- 行号变量
NR
:表示当前行号
示例:awk '{print NR, $0}' file.txt
打印行号+整行
- 字段分割与访问
- 默认分隔符:空格或制表符
- 字段变量:
$0
(整行)、$1
(第1字段)、$2
(第2字段)…$NF
(最后字段) - 字段总数
NF
:示例:awk '{print "共", NF, "个字段,最后字段:"$NF}' file.txt
- 自定义分隔符(-F 选项)
- 示例:
awk -F ',' '{print $1, $3}' data.csv
(按逗号分割CSV) - 多分隔符:
awk -F '[: ]' '{print $1}' /etc/passwd
(按冒号或空格分割)
四、模式(筛选行的条件)
- 正则表达式模式
- 格式:
/正则内容/
(匹配包含该内容的行) - 示例:
- 匹配 “success”:
awk '/success/ {print}' log.txt
- 排除 “error”:
awk '!/error/ {print}' log.txt
- 匹配 “success”:
- 比较表达式模式
- 运算符:
==
、!=
、>
、>=
、<
、<=
- 示例:
- 第2字段>100:
awk '$2 > 100 {print}' data.txt
- 第1字段是”admin”:
awk '$1 == "admin" {print}' user.txt
- 第2字段>100:
- 行号范围模式
- 用
NR
指定:awk 'NR >=5 && NR <=10 {print}' file.txt
(打印5-10行)
- BEGIN 与 END 块
BEGIN
:处理文件前执行(如打印表头)END
:处理文件后执行(如汇总结果)- 示例:
awk 'BEGIN {print "开始"} {print} END {print "共处理", NR, "行"}' file.txt
五、动作(处理行的操作)
- 打印操作
print
:直接输出(默认换行),如awk '{print $1, $3}' file.txt
printf
:格式化输出,如awk '{printf "姓名:%s,年龄:%d\n", $1, $2}' student.txt
- 格式符:
%s
(字符串)、%d
(整数)、%f
(浮点数)
- 格式符:
- 变量与运算
- 自定义变量:直接赋值(无需声明类型),如
sum = $2 + $3
- 常用运算:
+
-
*
/
(加减乘除)、+=
(累加) - 示例:计算平均值:
awk 'BEGIN {total=0} {total+=$2} END {print total/NR}' scores.txt
- 条件判断
- 语法:
if (条件) {动作} else {动作}
- 示例:
awk '{if ($2>=60) print $1,"及格"; else print $1,"不及格"}' scores.txt
六、数组基础
- 关联数组特性
- 键可以是字符串或数字,无需声明长度
- 赋值:
数组名[键] = 值
,如awk 'BEGIN {arr["name"]="Tom"; print arr["name"]}'
- 数组遍历
- 语法:
for (键 in 数组) {处理}
- 示例:
awk 'BEGIN {arr[1]="a"; arr[2]="b"; for(i in arr) print i, arr[i]}'
- 简单统计
- 示例:统计单词出现次数:
echo "a b a c" | awk '{for(i=1;i<=NF;i++) count[$i]++} END {for(w in count) print w, count[w]}'
七、官方示例解析
根据 awk -h
提供的示例,理解核心用法:
- 求和示例
gawk '{ sum += $1 }; END { print sum }' file
- 功能:计算文件中第1列所有数值的总和
- 解析:每行执行
sum += $1
(累加第1字段),最后在END
块打印总和
- 提取用户名示例
gawk -F: '{ print $1 }' /etc/passwd
- 功能:从系统用户文件中提取所有用户名
- 解析:用
-F:
指定冒号为分隔符,打印每行第1字段(用户名)
八、初级实战示例
- 内容提取
- 提取日志IP:
awk '{print $1}' access.log
- 提取CSV列:
awk -F ',' '{print $2, $4}' data.csv
- 数据统计
- 求和:
awk '{sum+=$3} END {print sum}' numbers.txt
- 统计行数:
awk 'END {print NR}' file.txt
- 格式转换
- 替换分隔符:
awk 'BEGIN {OFS=","} {print $1,$2,$3}' space.txt
(空格转逗号)
九、常见问题与解决
- 字段索引错误:区分
$0
(整行)和$1
(第1字段) - 分隔符问题:用
-F
明确指定分隔符(如处理CSV必须指定,
) - 变量未初始化:计算前用
BEGIN
初始化变量(如BEGIN {sum=0}
) - 过滤空行:
awk 'NF>0' file.txt
(NF>0
表示非空行)
十、GNU 扩展功能简述(进阶方向)
以下是一些 GNU AWK 的扩展功能,适用于复杂场景:
选项 | 功能描述 |
---|---|
-M | 支持高精度运算(如大数计算) |
-S | 沙盒模式,禁止危险操作(如 system() ) |
-D | 启动调试器(类似 gdb) |
-d | 导出变量信息(用于调试) |
-o | 美化输出 AWK 程序源码 |
-i | 包含其他 AWK 脚本文件 |
-l | 加载扩展库(如网络、数据库接口) |
十一、推荐练习资源
- GNU AWK Manual
- LeetCode AWK 编程题(适合进阶)
- 实战项目:日志分析、CSV 处理、报表生成等