文本三剑客之awk
简介:
awk 是面向文本处理的脚本语言,擅长按字段处理表格型文本(默认以空白分隔)。适用于日志分析、列计算、报表生成与简单的字符串处理。 GNU awk(gawk)还支持扩展特性与函数库。
基本语法:
1 | awk 'pattern { action }' file1 file2 ... |
模式(pattern)可以是正则表达式、条件表达式或 BEGIN/END 块。动作为一段用大括号括起来的语句序列。
常用内置变量:
- FS : 输入字段分隔符(默认空白,可设为正则或字符)
- OFS : 输出字段分隔符(默认空格)
- RS : 输入记录分隔符(默认换行)
- ORS : 输出记录分隔符(默认换行)
- NF : 当前记录的字段个数
- NR : 已读的记录数(跨文件累计)
- FNR : 当前文件的记录数(每个文件从1开始)
- FILENAME: 当前处理的文件名
常用选项:
- -F sep : 指定输入字段分隔符
- -v var=val : 在脚本外设置变量
- -f scriptfile : 从文件读取 awk 脚本
- –re-interval : 允许 {n,m} 之类的正则量词(部分 awk 已默认支持)
常见示例:
打印第1列与第3列:
1
awk '{print $1, $3}' file
以逗号分隔的 CSV 打印第2列:
1
awk -F',' '{print $2}' file.csv
统计某列求和(第3列为数值):
1
awk '{sum += $3} END {print sum}' file
按某列分组计数(类似 SQL: GROUP BY):
1
awk '{cnt[$1]++} END {for (k in cnt) print k, cnt[k]}' file
打印包含模式且显示行号:
1
awk '/error/ {print FILENAME ":" NR ":" $0}' *.log
过滤并格式化输出(printf 用法):
1
awk '{printf "%-20s %10d\n", $1, $2}' data.txt
只处理第 2~4 字段(改变 NF 后可重建行):
1
awk '{for(i=2;i<=4;i++) printf "%s%s", $i, (i<4?OFS:ORS)}' file
字段与字符串函数(常用):
- length(s) : 字符串长度(无参时为 $0 长度)
- substr(s, i, n)
- index(s, t)
- split(s, arr, sep)
- tolower(s), toupper(s)
- sprintf(fmt, …)
数组与关联数组:
awk 的数组是关联数组(索引为字符串)。常用于聚合、去重与连接模拟哈希表:
1 | awk '{a[$1] = a[$1] $2 ","} END {for (k in a) print k, a[k]}' file |
BEGIN / END 块:
- BEGIN 在读取任何输入前执行(初始化)
- END 在所有输入处理完后执行(汇总输出)
示例:1
awk 'BEGIN {print "Start"; OFS=","} {print $1, $2} END {print "Done"}' file
处理 CSV、复杂分隔与引号:
awk 原生对带引号的复杂 CSV 支持有限。简单 CSV 可用 -F’,’,复杂 CSV 推荐用专门库或工具(Python、csvkit、mlr)。
常见实用模式集:
- 去除空白行:awk ‘NF’
- 统计文件行数:awk ‘END{print NR}’ file
- 取出第 1 列唯一值:awk ‘{print $1}’ file | sort -u
- 根据第2列排序并取 topN(结合 sort):
awk ‘{print $2, $0}’ file | sort -nr | head
与其他工具结合:
- 与 sed/grep 联动过滤后用 awk 聚合:
grep ‘pattern’ file | awk ‘{…}’ - 与 sort/uniq 配合实现复杂分组统计:
awk ‘{print $1}’ file | sort | uniq -c | sort -nr
进阶与性能提示:
- 对大文件,尽量减少外部命令调用,使用内建函数与数组。
- 避免在循环中频繁执行子进程(如 system()),会显著慢。
- 对大量 CSV/JSON 等结构化数据,可考虑使用专门工具(jq、mlr、Python 的 pandas)或 gawk 的扩展库。
小结示例集:
1 | # 计算第3列的平均值 |
参考与扩展:
- 查看 man awk 或 man gawk
- GNU awk (gawk) 文档提供更丰富的扩展函数与库
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Kymlin's Blog!
评论


