悠悠楠杉
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 ""}'
 
                                            
                 
                         
                                