Linux awk 命令:结构化文本处理与数据提取入门

举报
yd_232564628 发表于 2026/10/09 09:50:50 2026/10/09
【摘要】 awk 的名字来自三位创始人 Alfred Aho、Peter Weinberger 和 Brian Kernighan 的姓氏首字母,诞生于 1977 年。与 grep 的"按行匹配"不同,awk 的核心思想是按列处理——它将每一行自动拆分成多个字段(列),然后对指定列执行操作。这使得 awk 在处理表格化数据(如日志、CSV、ps/df/netstat 等命令输出)时格外高效。 最基础的...

awk 的名字来自三位创始人 Alfred Aho、Peter Weinberger 和 Brian Kernighan 的姓氏首字母,诞生于 1977 年。与 grep 的"按行匹配"不同,awk 的核心思想是按列处理——它将每一行自动拆分成多个字段(列),然后对指定列执行操作。这使得 awk 在处理表格化数据(如日志、CSV、ps/df/netstat 等命令输出)时格外高效。

最基础的用法

awk '{print $1, $2}' file.txt
  • $1、$2 分别代表第 1 列、第 2 列,$0 代表整行。
  • 默认以空白字符(空格或 Tab)作为分隔符。
  • print 是 awk 最基本的动作,输出指定内容。

实际使用中,高频场景与命令组合

1. 指定分隔符

awk -F':' '{print $1, $3}' /etc/passwd

-F 指定字段分隔符。/etc/passwd 用冒号分隔,这条命令输出用户名(第 1 列)和 UID(第 3 列)。

处理 CSV 文件:

awk -F',' '{print $1, $5}' data.csv

2. 条件过滤

awk -F':' '$3 >= 1000 {print $1}' /etc/passwd

只输出 UID ≥ 1000 的普通用户名。awk 的条件写在 {} 前面,语法类似 C 语言。

3. 内置变量

变量 含义
NR 当前行号(全局)
FNR 当前文件的行号(多文件时各自计数)
NF 当前行的字段数(列数)
FS 输入分隔符(同 -F)
OFS 输出分隔符(默认空格)
# 输出第 5~10 行
awk 'NR>=5 && NR<=10' file.txt

# 输出每行的列数
awk '{print NR, NF}' file.txt

# 只输出列数大于 3 的行
awk 'NF > 3' file.txt

4. 统计计算

# 求第 2 列的总和
awk '{sum += $2} END {print sum}' file.txt

# 求平均值
awk '{sum += $2; count++} END {print sum/count}' file.txt

# 统计某列各值出现次数
awk '{count[$1]++} END {for (k in count) print k, count[k]}' file.txt

END 块在所有行处理完后执行,适合做汇总统计。

5. 格式化输出

awk '{printf "%-15s %8d\n", $1, $2}' file.txt

printf 支持 C 风格的格式化:%-15s 左对齐 15 字符宽的字符串,%8d 右对齐 8 字符宽的整数。比 print 更灵活。

6. 处理命令输出

# 查看占用内存最多的前 5 个进程
ps aux | awk '{print $2, $4, $11}' | sort -k2 -rn | head -5

# 统计 Nginx 访问日志中各状态码的数量
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

# 提取所有监听中的端口
ss -tlnp | awk 'NR>1 {print $4}' | grep -oP ':\K\d+$' | sort -un

7. 多文件处理

awk 'FNR==NR {a[$1]=$2; next} {print $1, a[$1]}' file1.txt file2.txt

这是一个经典模式:先读 file1.txt 建立查找表(数组 a),再读 file2.txt 时根据第 1 列查表输出。相当于用 awk 实现了简单的 join 操作。

8. BEGIN 和 END 块

awk 'BEGIN {FS=","; OFS="\t"; print "Name\tScore"} 
     {print $1, $2} 
     END {print "---"; print "Total lines:", NR}' data.csv
  • BEGIN 块在读取任何行之前执行,适合初始化变量、打印表头。
  • END 块在所有行处理完后执行,适合输出汇总信息。

9. 字符串函数

# 转大写
awk '{print toupper($1)}' file.txt

# 提取子串
awk '{print substr($1, 1, 5)}' file.txt

# 替换
awk '{gsub(/old/, "new", $0); print}' file.txt

# 长度
awk 'length($1) > 10' file.txt

10. 条件表达式

awk '{status = ($2 >= 60) ? "PASS" : "FAIL"; print $1, status}' scores.txt

支持三元运算符、if-else 等流程控制。

如果不知道如何下手,可以先尝试

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

这条命令从 df -h 的输出中提取文件系统、使用率和挂载点三列,快速查看磁盘使用情况。确认输出符合预期后,可以进一步加条件过滤:

df -h | awk 'NR>1 && int($5) > 80 {print $6, $5}'

找出使用率超过 80% 的分区。

或者,当你想快速统计 Nginx 日志中每个 IP 的访问次数时:

awk '{count[$1]++} END {for (ip in count) print count[ip], ip}' /var/log/nginx/access.log | sort -rn | head -10

awk 与相关工具对比

工具 特点 适用场景
grep 按行匹配 过滤包含某关键词的行
cut 按列提取 简单列提取,不支持计算
awk 按列处理 + 计算 结构化数据的提取、统计、格式化
sed 按行替换/编辑 文本替换、插入、删除

三者常配合使用:grep 过滤行 → awk 提取列 → sort | uniq 统计。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。