awk 是一种强大的文本处理工具,擅长对 结构化文本(如日志、CSV、配置文件)进行 逐行扫描、模式匹配、数据提取和计算。以下是它的核心语法解析和实用示例:
1. 基础语法结构
awk 'pattern {action}' [输入文件]
-
pattern:匹配条件(可选),如/error/或NR > 5。 -
action:对匹配行执行的操作,如print $1。 - 若省略
pattern:对所有行执行action。 - 若省略
action:默认打印匹配的整行。
2. 内置变量
3. 字段引用
-
$0:整行内容。 -
$1, $2, ... $NF:第1、第2...到最后一列。 -
$(NF-1):倒数第二列。
示例:打印每行的第一列和最后一列
awk '{print $1, $NF}' file.txt
4. 模式(Pattern)类型
(1) 正则匹配
awk '/error/ {print $0}' log.txt # 打印含 "error" 的行
awk '!/debug/ {print $2}' log.txt # 打印不含 "debug" 的行的第2列
(2) 行号匹配
awk 'NR >= 5 && NR <= 10' file.txt # 打印5到10行
(3) 字段条件
awk '$3 > 100 {print $1}' data.csv # 第3列大于100时打印第1列
(4) BEGIN/END 块
awk 'BEGIN {sum=0} {sum+=$1} END {print sum}' nums.txt # 计算第1列总和
5. 常用操作(Action)
(1) 打印控制
awk '{print "Line", NR, ":", $0}' file.txt # 自定义输出格式
(2) 计算与统计
awk '{sum+=$1; count++} END {print "Avg:", sum/count}' data.txt
(3) 字段重排
awk '{print $3, $1, $2}' file.txt # 按第3、第1、第2列顺序输出
(4) 条件分支
awk '{if ($1 > 50) print "High"; else print "Low"}' data.txt
6. 高级用法
(1) 自定义分隔符
awk -F',' '{print $2}' data.csv # 输入分隔符为逗号
awk 'BEGIN{FS="[:;]"} {print $2}' # 分隔符可以是正则(如 `:` 或 `;`)
(2) 多文件处理
awk '{print FILENAME, $0}' file1.txt file2.txt # 打印文件名和内容
(3) 关联数组(哈希表)
awk '{count[$1]++} END {for (k in count) print k, count[k]}' log.txt
# 统计第一列各值的出现次数
(4) 调用外部命令
awk '{system("echo " $1 " | tr a-z A-Z")}' names.txt # 调用系统命令
7. 经典案例
(1) 统计日志中每种状态的次数
awk '{status[$9]++} END {for (s in status) print s, status[s]}' access.log
# 假设第9列是HTTP状态码(如200、404)
(2) 提取CSV的特定列
awk -F',' '$3 ~ /2023/ {print $1, $4}' data.csv # 第3列含"2023"时输出1、4列
(3) 过滤重复行
awk '!seen[$0]++' file.txt # 仅保留第一次出现的行
(4) 数据格式化
awk '{printf "%-10s %5d\n", $1, $2}' table.txt # 左对齐名称,右对齐数字
8. 注意事项
- 字段编号从1开始,
$0是整行。 - 默认行为:无
pattern时匹配所有行,无action时打印整行。 - 性能:处理大文件时,避免在循环中频繁打印。
- 兼容性:不同系统上的
awk实现(如 GNU awkgawk)可能有扩展功能。
掌握这些语法后,你可以用 awk 高效处理日志分析、数据清洗、报表生成等任务!