awk 是 Linux/Unix 系统中最强大的文本处理工具 之一,是一门完整的编程语言,专门用于处理结构化文本(按列分隔的数据)。
核心定位
| 工具 |
擅长处理 |
grep |
按行筛选(找包含某内容的行) |
sed |
按行编辑(替换、删除) |
awk |
按列处理(提取、计算、格式化) |
基本语法
复制代码
awk '模式 {动作}' 文件
awk 'pattern {action}' file
执行逻辑 :逐行读取文件,匹配模式 的行执行动作。
核心概念:字段(列)
awk 自动按空格/制表符分割每行,生成内置变量:
| 变量 |
含义 |
$0 |
整行内容 |
$1 |
第1列 |
$2 |
第2列 |
$NF |
最后一列(N umber of Fields) |
$(NF-1) |
倒数第2列 |
NF |
当前行的列数 |
基础示例
1. 打印指定列(最常用)
复制代码
# 打印第1、3列(默认空格分隔)
awk '{print $1, $3}' file.txt
# 打印用户名和家目录(/etc/passwd 是冒号分隔)
awk -F: '{print $1, $6}' /etc/passwd
# 打印最后一列
awk '{print $NF}' file.txt
2. 指定分隔符 -F
复制代码
# CSV 文件(逗号分隔)
awk -F, '{print $2}' data.csv
# 多字符分隔符
awk -F' |,' '{print $1}' file.txt # 空格或逗号
3. 条件过滤
复制代码
# 打印第3列大于100的行
awk '$3 > 100 {print $0}' data.txt
# 匹配正则:包含 "error" 的行
awk '/error/ {print $0}' log.txt
# 组合条件:第2列为 "success" 且第5列大于10
awk '$2=="success" && $5>10 {print $1}' log.txt
内置变量
| 变量 |
含义 |
NR |
当前行号 (N umber of Record) |
NF |
当前行的列数 |
FS |
输入分隔符(F ield Separator,默认空格) |
OFS |
输出分隔符(O utput FS,默认空格) |
RS |
输入记录分隔符(默认换行) |
ORS |
输出记录分隔符(默认换行) |
进阶用法
1. BEGIN 和 END 块
复制代码
# BEGIN: 处理前执行(初始化)
# END: 处理后执行(汇总)
awk 'BEGIN {print "开始处理"}
{print NR, $0}
END {print "总行数:", NR}' file.txt
2. 计算统计
复制代码
# 求第3列的总和与平均
awk '{sum+=$3} END {print "总和:", sum, "平均:", sum/NR}' data.txt
# 统计行数(类似 wc -l)
awk 'END {print NR}' file.txt
# 找出文件第3列的最大值 NR==1为真,执行{max=$3} 其他行只检查$3>max,真则更新
awk 'NR==1 || $3>max {max=$3} END {print max}' data.txt
3. 格式化输出
复制代码
# printf 格式化(类似 C 语言)Name: %-10s 字符串格式:左对齐(-),占10个字符宽(10)
# Age: %3d 整数格式:右对齐(默认),占3个字符宽(3)
awk '{printf "Name: %-10s Age: %3d\n", $1, $2}' file.txt
# 对齐输出 %8.2f 第3列 右对齐(默认) 8字符 浮点数(2位小数)
awk '{printf "%-15s %10s %8.2f\n", $1, $2, $3}' report.txt
4. 修改字段内容
复制代码
# 替换第2列的值 将文件中每行的第2列替换为固定的字符串 "REPLACED",然后输出修改后的整行内容。
awk '{$2="REPLACED"; print $0}' file.txt
# 大小写转换
awk '{print toupper($0)}' file.txt # 转大写
awk '{print tolower($1)}' file.txt # 第1列转小写
实战场景
日志分析
复制代码
# 统计 HTTP 状态码出现次数
awk '{count[$9]++} END {for(code in count) print code, count[code]}' access.log
# 计算平均响应时间(假设第10列是响应时间)
awk '{sum+=$10; n++} END {print "Avg:", sum/n "ms"}' access.log
系统信息处理
复制代码
# 查看内存使用情况(过滤 + 计算)
free -m | awk '/Mem:/ {printf "内存使用率: %.2f%%\n", $3/$2*100}'
# 统计进程内存占用总和
ps aux | awk '{sum+=$6} END {print "总内存:", sum/1024 "MB"}'
数据处理
复制代码
# CSV 转 JSON(简化版)
awk -F, 'BEGIN {print "["}
{printf "%s{\"name\":\"%s\",\"age\":%s}",
(NR>1?",\n":""), $1, $2}
END {print "\n]"}' data.csv
# 去重(基于某列)
awk '!seen[$1]++' file.txt # 保留第1列首次出现的行
与 grep、sed 配合
复制代码
# 管道组合:先过滤,再处理列
grep "error" app.log | awk '{print $1, $4, $NF}'
# 提取 + 替换
awk '{print $2}' data.txt | sed 's/old/new/'
# 复杂处理:awk 内部调用系统命令
awk '{system("mkdir " $1)}' dirs.txt # 根据列内容创建目录
常用技巧速查
| 需求 |
命令 |
| 打印第2列 |
awk '{print $2}' |
| 按逗号分隔取第3列 |
awk -F, '{print $3}' |
| 打印行号 |
awk '{print NR, $0}' |
| 过滤空行 |
awk NF 或 awk '/./' |
| 去重 |
awk '!a[$0]++' |
| 替换分隔符输出 |
awk '{print $1","$2}' OFS=, |
| 条件过滤后统计 |
awk '$3>50{c++} END{print c}' |
完整脚本示例
复制代码
# 统计销售额报表
awk -F, '
BEGIN {
print "======== 销售报表 ========"
print "日期 产品 金额"
print "------------------------"
}
NR>1 { # 跳过表头
sum+=$3
count[$2]++ # 按产品统计
print $1, $2, $3
}
END {
print "------------------------"
print "总计:", sum
print "产品种类:"
for(p in count) print " " p ": " count[p] "次"
}
' sales.csv
总结
| 特性 |
说明 |
| 核心优势 |
按列处理、内置计算、格式化输出 |
| 语法 |
awk '模式{动作}' 文件 |
| 必记变量 |
$0, $1, $NF, NR, NF |
| 必记选项 |
-F 指定分隔符 |
一句话 :awk 是命令行里的 Excel,专门处理表格型数据,提取、计算、报表一把抓。