awk

awk 是 Linux 文本处理三大神器(grepsedawk)中功能最强的一个。

如果说:

  • grep:负责查找
  • sed:负责修改
  • awk:负责按字段处理、统计、计算、格式化输出

一句话概括:

awk 是一门专门处理结构化文本(按列、按字段)的脚本语言。

在日志分析、运维、数据处理、CSV 文件、系统监控等场景中使用极其频繁。


一、awk 工作原理

假设文件:

Tom 18 Beijing
Jack 20 Shanghai
Lucy 22 Shenzhen

执行:

awk '{print $1}' users.txt

输出:

Tom
Jack
Lucy

其中:

$1    第一列
$2    第二列
$3    第三列

awk 默认按空白字符(空格或 Tab)分列。


二、awk 最重要概念

例如:

Tom 18 Beijing

awk 看到的是:

变量 含义
$1 Tom
$2 18
$3 Beijing
$0 整行
NF 字段数量
NR 当前行号

例如:

awk '{print $0}'

输出整行。


三、最常用:print

打印第一列

awk '{print $1}'

打印多列

awk '{print $1,$3}'

输出:

Tom Beijing
Jack Shanghai

自定义输出

awk '{print "name=",$1,"age=",$2}'

输出:

name= Tom age= 18

四、指定分隔符(-F)

很多文件不是空格,而是:

Tom:18:Beijing

指定:

awk -F: '{print $1}'

输出:

Tom

CSV:

Tom,18,Beijing

使用:

awk -F, '{print $2}'

五、按条件筛选

例如:

Tom 18
Jack 20
Lucy 22

年龄大于20:

awk '$2>20'

输出:

Lucy 22

打印名字:

awk '$2>20{print $1}'

输出:

Lucy

多个条件:

awk '$2>18 && $2<30'

等于:

awk '$1=="Tom"'

六、统计(awk 最大优势)

求和

例如:

10
20
30
awk '{sum+=$1}END{print sum}'

输出:

60

平均值:

awk '{sum+=$1}END{print sum/NR}'

最大值:

awk 'max<$1{max=$1}END{print max}'

最小值:

awk 'NR==1{min=$1}min>$1{min=$1}END{print min}'

七、BEGIN 和 END

awk 有三个阶段:

BEGIN

处理每一行

END

例如:

awk '
BEGIN{
    print "start"
}
{
    print $1
}
END{
    print "end"
}'

输出:

start
Tom
Jack
Lucy
end

八、格式化输出(printf)

例如:

awk '{printf "%-10s %5d\n",$1,$2}'

输出:

Tom           18
Jack          20
Lucy          22

print 更适合生成报表。


九、统计出现次数

例如:

日志:

INFO
INFO
ERROR
WARN
INFO

统计:

awk '{count[$1]++}END{
    for(i in count)
        print i,count[i]
}'

输出:

INFO 3
ERROR 1
WARN 1

十、统计文件行数

虽然:

wc -l

更简单。

awk:

awk 'END{print NR}'

统计字段:

awk '{print NF}'

输出:

3
3
3

十一、处理 CSV

例如:

name,age,salary
Tom,18,5000
Jack,20,8000

工资:

awk -F, '{print $3}'

工资大于6000:

awk -F, '$3>6000'

跳过标题:

awk -F, 'NR>1'

十二、awk + grep

例如:

ps -ef |
grep nginx |
awk '{print $2}'

得到:

PID。


更推荐:

ps -ef |
awk '/nginx/{print $2}'

少一个 grep。


十三、awk + find

例如:

统计代码:

find . -name "*.go" |
awk '{print NR,$0}'

输出:

1 main.go
2 user.go

十四、awk + xargs

例如:

删除 PID:

ps -ef |
awk '/java/{print $2}' |
xargs kill

Docker:

docker ps |
awk 'NR>1{print $1}' |
xargs docker stop

十五、日志分析(生产环境)

日志:

2024 INFO login
2024 ERROR timeout
2024 ERROR mysql

错误:

awk '$2=="ERROR"'

统计:

awk '$2=="ERROR"{count++}
END{
print count
}'

十六、系统监控

CPU:

top -bn1 |
awk '/Cpu/{print $2}'

内存:

free -m |
awk '/Mem/{print $3}'

磁盘:

df -h |
awk 'NR>1{print $5,$6}'

十七、网络分析

查看监听:

ss -tunlp |
awk 'NR>1{print $5}'

IP:

ip addr |
awk '/inet /{print $2}'

十八、修改输出格式

例如:

Tom 18

变:

Tom:18
awk '{print $1":"$2}'

十九、变量

Shell:

age=18

awk:

awk -v age="$age" '$2>age'

二十、内置变量

变量 含义
NR 当前行号
NF 当前行字段数
FNR 当前文件行号
FS 输入分隔符
OFS 输出分隔符
RS 记录分隔符
ORS 输出记录分隔符

例如:

awk 'BEGIN{OFS=","}{print $1,$2}'

输出:

Tom,18

二十一、生产环境经典案例

查看 TOP10 大内存进程

ps aux |
sort -k4 -nr |
head |
awk '{print $2,$4,$11}'

查看磁盘使用

df -h |
awk 'NR>1{
print $6,$5
}'

查看登录用户

who |
awk '{print $1,$5}'

nginx 日志统计 IP

awk '{count[$1]++}
END{
for(i in count)
print i,count[i]
}' access.log

统计 HTTP 状态码

awk '{code[$9]++}
END{
for(i in code)
print i,code[i]
}' access.log

统计访问最多 IP

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

二十二、awk 常用函数

函数 作用
length() 长度
substr() 截取
split() 分割
tolower() 小写
toupper() 大写
gsub() 替换
index() 查找

例如:

awk '{print toupper($1)}'

输出:

TOM

二十三、awk 思维模型

可以把 awk 理解成一个按记录(行)+ 字段(列)处理的迷你编程语言

BEGIN
    初始化
       │
       ▼
读取一行
       │
       ▼
按 FS 分列
       │
       ▼
满足条件?
       │
       ├── 否 → 下一行
       ▼
执行动作(print / 统计 / 计算)
       │
       ▼
下一行……
       │
       ▼
END
输出统计结果

二十四、awk 常用语法速查

功能 命令
打印第一列 awk '{print $1}'
打印整行 awk '{print $0}'
指定分隔符 awk -F, '{print $2}'
条件过滤 awk '$2>100'
求和 awk '{sum+=$1}END{print sum}'
平均值 awk '{sum+=$1}END{print sum/NR}'
统计次数 awk '{cnt[$1]++}END{for(i in cnt)print i,cnt[i]}'
格式化输出 awk '{printf "%s %d\n",$1,$2}'
跳过首行 awk 'NR>1'
修改输出分隔符 awk 'BEGIN{OFS=","}{print $1,$2}'

二十五、grep、sed、awk 如何选择?

工具 最擅长的场景
grep 查找包含某个模式的行(过滤)
sed 替换、删除、插入文本(编辑)
awk 按列提取、统计、计算、格式化输出(分析)

实际工作中,它们经常组合使用:

grep ERROR app.log \
| awk '{count[$5]++} END {for (k in count) print k, count[k]}' \
| sort -k2 -nr

这种 grep + awk + sort + uniq + xargs 的组合,是 Linux 运维、日志分析和数据处理中的经典工作流。

posted @ 2026-07-10 16:35  ZovoeY  阅读(30)  评论(0)    收藏  举报