news 2026/5/10 2:56:36

Linux awk 命令:文本处理的瑞士军刀

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux awk 命令:文本处理的瑞士军刀

awk 是 Linux 下最强大的文本处理工具之一,名字取自三位创始人 Aho、Weinberger、Kernighan 的姓氏首字母。很多人只用它做简单的列提取,其实 awk 的能力远不止于此。

awk 的核心模型

awk 的工作流程可以概括为:

awk 'pattern { action }' file
  • pattern:匹配条件(正则、表达式、范围)
  • action:执行的操作(打印、计算、变量赋值)

对于每一行,awk 会:

  1. 自动按分隔符分割字段(默认空格)
  2. 字段存入$1, $2, $3...,整行是$0
  3. 检查 pattern,匹配则执行 action
# 提取第一列和第三列awk'{ print $1, $3 }'data.txt# 只处理包含 "error" 的行awk'/error/ { print $0 }'app.log# 计算文件总行数awk'END { print NR }'data.txt

NR是内置变量,表示当前行号(Number of Records)。END是特殊模式,在所有行处理完后执行。

字段分隔符:不只是空格

-F参数指定字段分隔符:

# CSV 文件按逗号分割awk-F',''{ print $1, $3 }'data.csv# 使用正则表达式:一个或多个空格awk-F'[ ]+''{ print $1 }'data.txt# 多字符分隔符awk-F'|''{ print $1 }'data.txt

也可以在脚本内设置FS(Field Separator):

awk'BEGIN { FS = "," } { print $1, $3 }'data.csv

BEGIN在处理任何行之前执行,常用于初始化变量。

内置变量的秘密

awk 提供了多个内置变量:

变量含义
$0整行内容
$1~$n第 n 个字段
NF当前行字段数(Number of Fields)
NR当前行号(全局)
FNR当前行号(当前文件)
FS字段分隔符
OFS输出字段分隔符
RS行分隔符
ORS输出行分隔符

NF的妙用:引用最后一个字段

# 打印每行的最后一个字段awk'{ print $NF }'data.txt# 打印倒数第二个字段awk'{ print $(NF-1) }'data.txt

条件判断与循环

awk 支持if-elsefor/while循环:

# 按条件过滤并标记awk'{ if ($3 > 100) { print $1, "HIGH" } else { print $1, "NORMAL" } }'data.txt# 计算每行的字段和awk'{ sum = 0 for (i = 1; i <= NF; i++) { sum += $i } print sum }'numbers.txt

数组与统计

awk 的数组是关联数组(associative array),键可以是任意字符串:

# 统计每个单词出现次数awk'{ for (i = 1; i <= NF; i++) { count[$i]++ } } END { for (word in count) { print word, count[word] } }'text.txt# 按访问量统计 HTTP 状态码awk'{ count[$9]++ } END { for (code in count) print code, count[code] }'access.log

这段代码中$9是 Nginx 日志的状态码字段(假设标准格式)。

实战案例:分析 Nginx 访问日志

假设日志格式:

192.168.1.1 - - [10/May/2026:10:30:45 +0800] "GET /api/users HTTP/1.1" 200 1234 "-" "Mozilla/5.0"

1. 统计 Top 10 访问 IP

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

纯 awk 实现:

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

2. 计算平均响应时间

假设日志格式包含响应时间(最后一个字段):

awk'{ total += $NF count++ } END { print "Average:", total/count, "ms" }'access.log

3. 提取 4xx 和 5xx 错误

# 提取所有 4xx 和 5xx 状态码的请求awk'$9 ~ /^[45][0-9][0-9]$/ { print $0 }'access.log# 统计错误类型分布awk'$9 ~ /^[45][0-9][0-9]$/ { errors[$9]++ } END { for (code in errors) print code, errors[code] }'access.log

~是正则匹配操作符,$9 ~ /^.../表示第 9 个字段匹配正则。

性能优化技巧

1. 跳过无效行

next跳过不需要处理的行:

awk'/^#/ { next } { print $1 }'config.conf

跳过注释行(以#开头)。

2. 只处理前 N 行

awk'NR > 100 { exit } { print $1 }'data.txt

处理前 100 行后退出,避免读取整个大文件。

3. 多文件处理时的 FNR

当处理多个文件时,NR是全局行号,FNR是当前文件行号:

# 每个文件单独统计awk'FNR == 1 { print "File:", FILENAME } { print NR, FNR, $0 }'file1.txt file2.txt

复杂案例:计算移动平均

假设有一个温度数据文件,每行一个温度值,计算 3 点移动平均:

awk'{ values[NR] = $1 if (NR >= 3) { sum = values[NR] + values[NR-1] + values[NR-2] print (NR-2), sum/3 } }'temperature.txt

awk vs sed vs grep

很多人分不清这三个工具的边界:

工具核心能力典型场景
grep行过滤快速搜索匹配行
sed流编辑替换、删除、插入
awk字段处理 + 计算统计、报表、格式化

三者常组合使用:

# 组合示例:提取 error 行,替换时间戳格式,统计按小时分布grep"ERROR"app.log|\sed's/\[.*\]//'|\awk'{ count[$1]++ } END { for (h in count) print h, count[h] }'

小结

awk 的强大在于:

  1. 自动字段分割,省去手动 split
  2. 完整的编程语言(变量、数组、函数、循环)
  3. 内置的模式匹配机制

掌握 awk,处理文本文件就像用 SQL 查询数据库一样高效。复杂的统计、格式化、转换任务,一行 awk 命令就能搞定。


相关工具:Linux sed 命令 | 文本去重工具 | Grep 命令详解

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/10 2:44:48

k8s-tew:专为边缘与离线场景设计的轻量Kubernetes发行版实战指南

1. 项目概述&#xff1a;一个专为边缘与实验室场景打造的轻量K8s发行版如果你和我一样&#xff0c;经常需要在资源受限的边缘设备、本地开发机&#xff0c;甚至是单台笔记本电脑上折腾Kubernetes&#xff0c;那你一定对kubeadm、minikube、k3s这些名字不陌生。但每次搭建&#…

作者头像 李华
网站建设 2026/5/10 2:41:37

开源AI智能体中心:统一管理Claude、Cursor等工具的提示词与工作流

1. 项目概述&#xff1a;一个跨平台、跨部门的AI智能体中心如果你和我一样&#xff0c;每天都在和Claude Code、Cursor、ChatGPT、Gemini这些AI工具打交道&#xff0c;那你肯定也遇到过这个痛点&#xff1a;每次开始一个新项目&#xff0c;或者切换一个工作角色&#xff0c;都得…

作者头像 李华
网站建设 2026/5/10 2:37:33

IncreRTL:基于LLM的硬件设计增量代码生成技术

1. 项目概述 在硬件设计自动化领域&#xff0c;寄存器传输级(RTL)代码生成一直是连接自然语言需求与电路实现的关键环节。随着大语言模型(LLMs)技术的快速发展&#xff0c;基于LLM的RTL自动生成技术展现出巨大潜力。然而&#xff0c;现有方法在面对需求演化时存在明显不足&…

作者头像 李华