极简工具箱

免费在线工具 · 本地计算 · 无需上传

awk 入门:按列取值、条件过滤与求和统计

日志里只要第 7 列的那个耗时数字,`cut` 遇到多个空格就切不准了,而 `awk` 一行就能取出来并求和。

广告位(百度联盟)

一、基本模型:模式 + 动作

awk '条件 { 动作 }' 文件

不写条件就是「每一行都执行」,不写动作就是「打印整行」。

awk '{print $1}' file        # 打印第一列
awk '{print $1, $3}' file    # 打印第 1、3 列(逗号会输出空格)
awk '{print NF}' file        # 每行有多少列
awk '{print $NF}' file       # 最后一列

$0 是整行,$1 是第一列,NF 是列数(所以 $NF 就是最后一列)。这是 awk 最核心的几个变量。

二、分隔符

默认按连续空白(空格或 Tab)分割,这比 cut -d' ' 强——多个空格不会切出空列。

awk -F: '{print $1}' /etc/passwd       # 按冒号
awk -F',' '{print $2}' data.csv        # 按逗号
awk -F'\t' '{print $3}' file           # 按 Tab

-F 也支持正则,比如 -F'[;,|]' 同时按三种符号切。

三、条件过滤

awk '$3 > 100' file                       # 第 3 列大于 100
awk '$2 == "ERROR" {print $0}' app.log    # 第 2 列等于 ERROR
awk '/Timeout/ {print $1, $NF}' app.log   # 整行匹配正则
awk 'NR>=10 && NR<=20' file               # 第 10–20 行

NR 是当前行号(跨文件累计),FNR 是当前文件内的行号,处理多个文件时用 FNR 更准。

四、统计:求和、计数、平均

# 求和
awk '{sum += $3} END {print sum}' file

# 计数
awk '/ERROR/ {n++} END {print n}' app.log

# 平均值(注意除零)
awk '{s += $3; n++} END {if (n) printf "%.2f\n", s/n}' file

END 块在所有行处理完后执行一次,是放汇总逻辑的地方。BEGIN 则在读取前执行,常用来打印表头或初始化变量。

日志耗时统计的实用写法:

awk -F'cost=' '{split($2, a, "ms"); s += a[1]} END {print s "ms"}' access.log

五、格式化输出

awk '{printf "%-20s %8.2f\n", $1, $3}' file

%-20s 左对齐 20 字符,%8.2f 右对齐 8 宽保留两位小数。做对齐的文本报表时比 echo 拼字符串方便。

六、四个能直接用的命令

# 1. 访问日志里耗时最长的 10 个请求
awk '{print $NF, $0}' access.log | sort -rn | head -10

# 2. 统计每个 IP 的请求数 Top10
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10

# 3. 统计各状态码数量
awk '{print $9}' access.log | sort | uniq -c | sort -rn

# 4. 计算某列总和与平均
awk '{s+=$5; n++} END {printf "sum=%d avg=%.2f\n", s, s/n}' data.txt

这几个组合(sort | uniq -c | sort -rn)是日志分析的万能套路,值得记住。

七、注意点

小结

$1 取列、$NF 取最后一列、-F 指定分隔符、NR 是行号、END 做汇总。配合 sort | uniq -c | sort -rn 能解决大部分日志统计需求。

本文相关工具(本地计算,无需上传)

更多使用教程