awk 命令速查表 - Linux 文本处理常用命令大全

日志和报表的共同特征是「一行一个字段」,而 awk 的杀手锏正是按列干活:统计 nginx 日志里各状态码占比、按用户分组求和,一条命令顶一段脚本。表从基础语法、内置变量、条件判断、统计与计算、字符串函数到常用场景六组展开,对应完整处理骨架:pattern 加 action 是每行基本结构,BEGIN 与 END 分别负责预处理和收尾汇总。最该先记住的是内置变量:FS 是输入分隔符、OFS 是输出分隔符、NR 是全局行号、NF 是当前行字段数。统计一组的核心是关联数组:count[$9]++ 按字段值计数,sum[group]+=value 按分组累加,配合 END 输出就是一份完整报表。分工要说清:sed 逐行改写而不理解列结构,awk 理解列才能聚合;cut 只取列不做计算。输入 CSV 时用 FPAT 处理引号内的逗号。

系统与运维·共 37 条命令·最后更新 2026-07-21

典型使用场景

面向做报表统计与日志分析的工程师。awk 与 sed 的分工要记牢:sed 按行改或删,awk 按列取数与计算。本表按基础语法、内置变量、条件判断、统计计算、字符串函数、常用场景六组组织。最实用的三个模式是「取列统计」`awk '{print $1}' | sort | uniq -c | sort -rn`、`按条件取数」`awk '$9 == 500 {print $7}'`,以及 BEGIN/END 块做前后处理——这两块是 awk 与其它文本工具的关键差异。

基础语法 Basic Syntax 6

awk '{print $1}' file
打印第一列(默认空格分隔)
awk -F: '{print $1, $3}' /etc/passwd
指定冒号分隔符
awk '{print $1, $NF}' file
打印第一列和最后一列
awk '{print NR, $0}' file
打印行号和整行
awk 'NR==10' file
打印第 10 行
awk 'NR>=10 && NR<=20' file
打印第 10-20 行

内置变量 Built-in Variables 8

$0
整行内容
$1, $2, $NF
第 1/2/最后一列
NR
当前行号(全局)
NF
当前行列数
FS
输入分隔符(默认空格)
OFS
输出分隔符
RS
输入记录分隔符(默认换行)
ORS
输出记录分隔符

条件判断 Conditionals 6

awk '$3 > 100' file
打印第三列大于 100 的行
awk '$1 == "error"' file
打印第一列等于 error 的行
awk '$1 ~ /pattern/' file
第一列匹配正则
awk '$1 !~ /pattern/' file
第一列不匹配正则
awk 'NR==1 || $1 > 100' file
第一行或第一列大于 100
awk '$1 == "a" {print $2}' file
条件动作

统计与计算 Statistics 5

awk '{sum += $1} END {print sum}' file
对第一列求和
awk '{sum += $1} END {print sum/NR}' file
计算第一列平均值
awk '{count++} END {print count}' file
统计行数
awk '{count[$1]++} END {for(k in count) print k, count[k]}' file
按第一列分组统计
awk 'BEGIN{max=0} {if($1>max) max=$1} END{print max}' file
找第一列最大值

字符串函数 String Functions 7

length($0)
当前行长度
substr($0, 5, 10)
从第 5 个字符开始截取 10 个
index($0, "text")
查找子串位置(1 开始,0 表示未找到)
split($0, arr, ":")
按分隔符拆分为数组
sub(/old/, "new", $0)
替换第一个匹配
gsub(/old/, "new", $0)
替换所有匹配
tolower($0) / toupper($0)
转小写/大写

常用场景 Common Patterns 5

awk '{print $1}' access.log | sort | uniq -c | sort -rn
统计 IP 访问量 TOP
awk '$9 == 500 {print $7}' access.log
提取 500 错误的 URL
awk -F, '{print $2, $3}' data.csv
处理 CSV 文件
awk 'BEGIN{OFS=","} {print $1, $2}' file
输出为 CSV 格式
awk '{sum+=$5} END{print sum/1024/1024 " MB"}' file
计算列总和并转换单位

参数矩阵

参数作用示例
{print $1}打印第 1 列(默认空白分隔)awk '{print $1}' file
-F<sep>指定输入分隔符awk -F: '{print $1, $3}' /etc/passwd
$0整行内容awk '{print NR, $0}' file
$NF最后一列(列数不定时最有用)awk '{print $1, $NF}' file
NR / NF当前行号 / 当前行列数awk 'NR==10' file
FS / OFS输入 / 输出分隔符awk 'BEGIN{OFS=","} {print $1, $2}' file
$3 > 100数值比较(awk 自动识别数字)awk '$3 > 100' file
$1 ~ /pat/正则匹配(!~ 为不匹配)awk '$1 ~ /^error/' app.log
BEGIN / END处理前 / 处理后执行一次awk '{sum+=$1} END {print sum}' file
sum += $1累加,可结合 END 输出awk '{sum+=$1} END {print sum/NR}' file
count[$1]++关联数组分组计数awk '{c[$1]++} END {for(k in c) print k, c[k]}' file
sub / gsub替换第一个 / 全部匹配gsub(/old/, "new", $0)
split / substr按分隔符拆数组 / 截取子串split($0, arr, ":")
管道组合与 sort / uniq 组合做统计awk '{print $1}' f | sort | uniq -c | sort -rn

易错点与避坑指南

现象awk 取到的列全是空的或整行被当成一个字段。

原因分隔符不匹配——文件是冒号分隔却没加 -F:,awk 默认按空白切。

处置先用 head 看一眼真实分隔符,再用 awk -F: 或 -F, 指定正确分隔符。

现象sum 统计结果为 0 或异常大。

原因列中含有非数字字符(如单位、时间戳),被按 0 参与运算。

处置用 head 确认数据格式;必要时先 gsub 去掉非数字字符,或改用 $1+0 显式转数。

现象END 块里访问不到累加变量。

原因累加变量在主块与 END 块中的作用域不一致(常见于把变量声明在条件分支内)。

处置在 BEGIN 块里初始化累加器,或确保累加语句在顶层而非某个分支内首次赋值。

现象awk 里的正则匹配不到内容。

原因正则中的特殊字符(. * + ? [ ])需要转义。

处置字面匹配用 /\./ 或 index/substr 代替正则;~ 两侧不要写字符串引号。

现象统计每个项的次数,结果全是 1。

原因管道漏了 sort,awk 的关联数组本身不排序,但未先聚合导致重复项被覆盖。

处置写全四步:awk 提取 | sort | uniq -c | sort -rn。

现象输出列之间连在一起,没有分隔。

原因print 对多个表达式默认用 OFS 分隔,但 OFS 未显式设置且用逗号分隔的写法被当成了字符串拼接。

处置BEGIN{OFS=","} 设置输出分隔符;print $1, $2 用逗号分隔表达式。

现象处理带空格的字段时整行被切开。

原因默认 FS 是空白(含空格与 Tab),字段值内部有空格时会被拆开。

处置把 FS 设为固定单字符:-F" " 或 -F"|"。

排障路径

  1. 1先确认数据分隔符与列位置

    head -3 file

    看清真实分隔符再写表达式,能避免大部分「取不到列」的返工。

  2. 2统计访问量 TOP 20

    awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -20

    取列 → 排序聚合 → 计数 → 按数值降序,四步缺一不可。

  3. 3按条件提取字段

    awk '$9 == 500 {print $7}' access.log

    $9 是状态码、$7 是 URL;条件放前面 {} 放动作。

  4. 4计算列总和并换算单位

    awk '{sum+=$5} END {print sum/1024/1024 " MB"}' file

    END 块输出结果,字符串拼接单位最直观。

  5. 5按第一列分组统计

    awk '{c[$1]++} END {for(k in c) print k, c[k]}' file

    awk 的数组是关联数组,可直接用任意值做键。

命令示例

按第一列分组计数

awk '{count[$1]++} END {for(k in count) print k, count[k]}' access.log | sort -k2 -rn | head

count[$1]++ 用数组下标做键,逐行累加;END 块在全部读完后统一输出。再接 sort 才能按计数排序——awk 本身不排序。

输出

203.0.113.7 1842
198.51.100.22 931
192.0.2.180 407

求和并换算成 MB

awk '{sum += $5} END {printf "%.2f MB\n", sum/1024/1024}' access.log

END 里用 printf 控制输出精度与单位。除法要逐层写,awk 不支持 1024*1024 这样的幂运算符。

输出

482.31 MB

输出 CSV(设置 OFS)

awk -F, 'BEGIN{OFS=","} NR>1 {print $2, $3}' data.csv > out.csv

-F, 指定输入分隔符为逗号,OFS 指定输出分隔符。NR>1 跳过 CSV 的表头行,否则标题也会被写进结果。

常见坑与注意事项

  • 字段下标从 1 开始,$0 是整行;$1[0] 这类写法不成立。
  • awk 默认按空白分隔,解析 CSV 或冒号分隔文件必须显式 -F,否则会把整行当成一个字段。
  • OFS 要在 BEGIN 里设置一次,写在主规则里会被每行重置。
  • 处理 CSV 时引号内的逗号会被误当分隔符,简单场景可用 FPAT 进阶处理。
  • awk 不做排序,统计完必须接 sort | uniq,否则拿到的是无序结果。

提示

  • awk 默认以空格或 Tab 分隔,用 -F 指定其他分隔符。
  • BEGIN 块在处理文件前执行,END 块在处理完后执行。
  • awk 数组是关联数组(哈希表),键可以是字符串。
  • awk -v OFS="\t" '{print $1,$2}' 可以把默认的空格输出改成制表符,直接粘进 Excel 不串列。
  • awk '{print NR": "$0}' 给每行加行号,排查「输出的第几行不对」时比用 nl -ba 更省一道管道。
  • NR 与 FNR 的区别在处理多文件时最有用:NR 是跨文件累计行号,FNR 是当前文件内的行号,用 FNR>1 跳过每个文件的首行表头。

常见问题

awk 的 $1 从 1 开始还是从 0 开始?

从 1 开始。$0 表示整行,$1 是第一个字段,$2 是第二个,以此类推,$NF 是最后一个字段。这个设计容易和数组下标混淆——数组同样是 arr[1] 起,但 awk 里 $1 指的是列而不是数组元素,$NF 这种写法在处理不定列数的文件时特别方便。

awk 怎么按分组做统计?

核心是 count 数组加 END 块:awk '{count[$1]++} END {for(k in count) print k, count[k]}' file 会按第一列分组统计出现次数。统计日志里各 IP 的访问量就是 awk '{print $1}' access.log | sort | uniq -c | sort -rn。求和用 awk '{sum += $1} END {print sum}',求平均再除以 NR。

NF 和 $NF 有什么区别?

NF 是当前行的字段数量(一个数字),$NF 是最后一个字段的内容(一个字符串)。这两个经常一起出现在可变列数的场景:NF < 3 时跳过这种格式不对的行,或者用 $(NF-1) 取倒数第二个字段。搞混的话 awk 会直接报类型错误。

awk 里怎么判断字段是否匹配正则?

用 ~ 运算符:awk '$1 ~ /pattern/' file 匹配,awk '$1 !~ /pattern/' file 取反。等价写法是 index($1, "pattern") 做子串查找,但 index 只找固定字符串,不支持正则。需要对整行匹配时直接用 /pattern/ 即可。

awk 怎么把输出变成 CSV?

设置输出分隔符 OFS 即可:awk 'BEGIN{OFS=","} {print $1, $2}' file 会用逗号分隔输出。注意只在 BEGIN 块里设一次,不要放进主规则,否则会被反复重置。想要带引号的 CSV 输出,可以额外加 OFS 与引号变量并在 print 时手动拼接。

官方参考来源

下方为命令对应的官方权威文档,供你核对最新用法与深入查阅。

由 巧匠 维护

公开更新于 2026年7月21日,内容持续校对官方文档。

联系我们

命令或描述有误?提交反馈、商务合作或产品建议都可发送邮件给我们。

联系我们