悠悠楠杉
Linux中的awk命令详解:文本处理三剑客之一
一、awk是什么?
awk是由Alfred Aho、Peter Weinberger和Brian Kernighan在1977年开发的文本处理工具(名字取自三人姓氏首字母)。它不仅是命令行工具,更是一门专为文本处理设计的编程语言,擅长处理行列结构的文本数据,如日志文件、CSV表格等。
与grep
(搜索)和sed
(替换)并称“Linux文本处理三剑客”,awk的核心优势在于:
- 字段自动分割:按空格或指定分隔符切分每行文本
- 内置变量:如NR
(行号)、NF
(字段数)
- 数学运算:直接支持加减乘除、数组等操作
二、基础语法与工作流程
1. 基本命令结构
bash
awk '模式 {动作}' 文件名
- 模式:可选条件,如/error/
匹配含"error"的行
- 动作:处理逻辑,如print $1
打印第一列
2. 执行流程
- 逐行读取输入文件
- 根据分隔符(默认空格/TAB)拆分字段(
$1
、$2
…) - 检查是否匹配“模式”
- 执行对应的“动作”
3. 示例:提取日志IP
bash
awk '{print $1}' access.log # 打印第一列(通常为IP地址)
三、核心功能详解
1. 内置变量
| 变量 | 说明 | 示例 |
|------|-----------------------|--------------------------|
| NR | 当前行号 | awk '{print NR, $0}'
|
| NF | 当前行的字段数 | awk '{print $NF}'
|
| FS | 输入字段分隔符 | awk -F':' '{print $1}'
|
| OFS | 输出字段分隔符 | awk -v OFS="|" '{print $1,$3}'
|
2. 条件过滤
bash
筛选第3列大于100的行
awk '$3 > 100 {print $0}' data.txt
匹配正则表达式(包含error的行)
awk '/error/ {print NR, $0}' logfile
3. 数学运算与统计
bash
计算第2列总和
awk '{sum += $2} END {print sum}' data.txt
求平均值
awk '{sum += $1; count++} END {print sum/count}' numbers.txt
四、高阶实战技巧
1. 多条件组合
bash
第1列为"admin"且第3列大于50
awk '$1 == "admin" && $3 > 50 {print $2}' users.txt
2. 字符串处理
bash
连接字段并格式化输出
awk '{printf "Name:%-10s Age:%d\n", $1, $2}' data.txt
提取子串(从第2列第3字符开始截取2位)
awk '{print substr($2, 3, 2)}' file
3. 数组与去重
bash
统计IP出现次数
awk '{ipcount[$1]++} END {for (ip in ipcount) print ip, ip_count[ip]}' access.log
去重显示第2列
awk '!seen[$2]++ {print $2}' duplicates.txt
五、常见应用场景
日志分析
bash
统计HTTP状态码分布
awk '{status[$9]++} END {for (s in status) print s, status[s]}' access.log
数据清洗
bash
将CSV转为竖线分隔
awk -F, -v OFS='|' '{print $1,$3,$5}' data.csv
报表生成
bash
计算各部门工资总额
awk -F: '{dept[$1]+=$2} END {for (d in dept) print d, dept[d]}' salary.txt
六、性能优化建议
减少管道操作:合并多个
awk
操作为一个脚本
bash
低效写法
cat file | awk '{print $1}' | awk '/foo/'
高效写法
awk '$1 ~ /foo/ {print $1}' file
预编译复杂脚本:对重复使用的脚本使用
-f
参数bash awk -f script.awk input.txt
避免全行匹配:指定列能提升速度
bash
慢
awk '/192.168.1.100/'
快(假设IP在第一列)
awk '$1 == "192.168.1.100"'
结语
掌握awk能让你在Linux环境下处理文本时事半功倍。从简单的字段提取到复杂的数据统计,awk的灵活性几乎能满足所有文本处理需求。建议在日常工作中多实践组合技巧,逐渐培养“awk思维”——将文本视为结构化数据流进行处理。
附:经典单行awk命令
bash打印文件行数(等效wc -l)
awk 'END {print NR}' file
反转字段顺序
awk '{for (i=NF; i>0; i--) printf "%s ", $i; print ""}'