Linux 文本处理三剑客实战:grep、sed、awk 在服务器运维中的应用

为什么站长一定要会点文本处理

个人站长和服务器打交道,本质上就是在和各种"文本"打交道:排错要看日志,改配置要编辑文件,统计访问量要分析 access.log,批量修改要同时处理几十个文件。服务器上没有图形界面,Windows 上那种"打开文件、查找替换、另存为"的操作习惯在这里行不通,一切都要靠命令行完成。

而命令行文本处理的核心,就是 grep、sed、awk 这三个工具。它们合称"文本处理三剑客":grep 负责找,sed 负责改,awk 负责算。三个工具再加上管道符组合使用,能解决运维中九成以上的文本处理需求。这篇文章不打算罗列参数大全,而是从真实运维场景出发,讲清楚每个工具最常用的用法,让你看完就能上手。

grep:从日志里快速定位问题

grep 的作用是从文本里筛出匹配的行,它是排错时用得最多的命令。最基本的用法是搜索关键词,比如 PHP 报错日志里今天有没有出现致命错误:

grep -E "Fatal error|Parse error" /var/log/php-fpm.log

实际使用中几乎总是会搭配几个选项:-i 忽略大小写,-n 显示行号方便回头看上下文,-v 反向匹配(排除某些行),--color 让匹配内容高亮。想看报错前后的上下文,用 -A 和 -B 指定后面和前面各显示几行:

grep -n -A 5 -B 2 "ERROR" /var/log/nginx/error.log

排错时经常需要"排除干扰项"。比如查看日志里非正常访问的请求,可以先排除健康检查的痕迹:

grep -v "127.0.0.1" /var/log/nginx/access.log | tail -20

还有一个非常实用的场景:统计某种状态码出现了多少次。Nginx 访问日志里状态码在第九个字段,用 grep 加正则可以直接数出来:

grep -c '" 5[0-9][0-9] ' /var/log/nginx/access.log

这里的 -c 不是显示匹配行,而是直接输出匹配行数。模式里的双引号是日志里的真实字符,5[0-9][0-9] 匹配 500 到 599 的所有状态码,也就是所有 5xx 错误。如果搜索的内容里含有大量特殊字符,不想写转义,可以加 -F 参数把模式当作固定字符串处理。

grep 还支持 -r 递归搜索整个目录,比如在网站源码里找所有调用某个已废弃函数的地方:

grep -rn "mysql_connect" /var/www/html/

sed:批量修改文件的瑞士军刀

sed 是流编辑器,它像流水线一样逐行读取文件、执行编辑命令、输出结果。最核心的用法是替换,语法是 s/旧内容/新内容/,末尾加 g 表示替换行内所有匹配而不只是第一个:

sed 's/旧内容/新内容/g' 文件名

注意,默认情况下 sed 只是把处理结果输出到屏幕,并不会真的修改文件。想要原地修改必须加 -i 参数,这也是新手最容易犯的错误——不加 -i 以为改成功了,文件其实原封不动;或者加了 -i 又因为替换表达式写错,把配置文件改坏了。稳妥的做法是加 -i 的同时带上备份后缀,让 sed 自动生成备份文件:

sed -i.bak 's/旧内容/新内容/g' /etc/php/8.2/fpm/php.ini

执行后同目录下会多出一个 php.ini.bak,万一改坏了可以一键还原。任何生产环境的批量修改都建议先这样留个后路。

实际运维中 sed 最常见的几个场景:批量把网站代码里的 http:// 链接替换成 https://;批量修改配置文件里的某个参数值;注释掉或删除某些行。比如给 Nginx 站点配置里所有被注释的配置块取消注释:

sed -i 's/^#//' /etc/nginx/conf.d/example.conf

再比如删除文件里所有的空行和注释行,让配置一目了然(只是输出预览,不会改动文件):

sed '/^#/d; /^$/d' /etc/nginx/nginx.conf

这里的 d 表示删除匹配的行,分号用来在同一行里串联多个命令。sed 还支持按行号操作,比如打印第 10 到 20 行:

sed -n '10,20p' /var/log/nginx/access.log

-n 参数的意思是"不默认输出每一行",配合 p 命令就实现了"只打印指定范围"。这个组合在看大文件指定区间时比 head、tail 灵活得多。

awk:按列统计的分析利器

grep 处理"行",awk 处理"列"。awk 会把每一行按分隔符切成若干字段,默认以空白(空格或 Tab)作为分隔符,第一个字段叫 $1,第二个叫 $2,整行叫 $0,最后一个字段可以用 $NF 表示。这一特性让它天生适合分析 access.log 这种格式规整的日志。

最简单的入门场景:取出访问日志里所有访客的 IP 地址,也就是每行的第一个字段:

awk '{print $1}' /var/log/nginx/access.log

光打印出来没什么用,配合管道组合出统计才是精髓。下面这条命令是运维里出现频率最高的组合拳之一——统计访问量最大的前十个 IP:

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

这条管道链的思路是:awk 取出 IP 列,sort 排序让相同 IP 相邻,uniq -c 统计每个 IP 出现次数,sort -rn 按次数从大到小排,head -10 取前十名。看懂这条链,就等于掌握了日志统计的基本方法论,把 $1 换成别的字段就能统计别的东西。

比如统计访问量最大的页面,取第七个字段(请求的 URL):

awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

awk 还能在读取时做条件判断。比如只看返回 502 的请求来自哪些 IP:

awk '$9 == 502 {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

这里 $9 == 502 是条件,只有满足条件的行才会执行后面的打印动作。同理可以统计出 404 最多的 URL(第九个字段是状态码,第七个是 URL):

awk '$9 == 404 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

除了默认的空白分隔,awk 还可以用 -F 指定其他分隔符。比如分析 /etc/passwd 文件(冒号分隔)取出用户名和登录 Shell:

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

awk 还支持累加运算,适合统计流量。Nginx 日志第十个字段是响应字节数,统计一天的总流量(单位字节):

awk '{sum += $10} END {print sum}' /var/log/nginx/access.log

END 表示所有行处理完之后执行一次,这种"逐行累加、最后汇总"的模式是 awk 处理数值统计的标准姿势。

再补充一个高频变量 $NF,它代表每行的最后一个字段,在处理字段数量不固定的行时非常好用。比如某些网站开启了 CDN,日志里会多出几列代理相关的字段,导致 URL 不在固定的第七个位置,这时用 $NF 或者 $(NF-1) 按行尾取字段,比死记硬背列号可靠得多:

# 取每行最后一个字段(如响应时间或 UA),预览前 5 行
awk '{print $NF}' /var/log/nginx/access.log | head -5

组合实战:一次完整的日志体检

把三个工具串起来,就能完成一次像样的日志体检。假设要回答"今天网站到底怎么样",可以依次执行这几条命令:

# 今天有多少次访问
grep "08/Sep/2026" /var/log/nginx/access.log | wc -l

# 今天有多少个独立访客 IP
grep "08/Sep/2026" /var/log/nginx/access.log | awk '{print $1}' | sort -u | wc -l

# 今天状态码分布
grep "08/Sep/2026" /var/log/nginx/access.log | awk '{print $9}' | sort | uniq -c | sort -rn

# 今天响应最慢的 10 个请求(第十一字段是响应时间)
grep "08/Sep/2026" /var/log/nginx/access.log | sort -k11 -rn | head -10 | awk '{print $11, $7}'

第一条用 grep 按日期筛出今天的日志再数行数,就是今天的 PV;第二条把 IP 列去重计数,得到 UV;第三条看状态码分布,能立刻发现 5xx 是否异常增多;第四条按响应时间字段排序,找出拖慢网站的慢请求。整个过程不需要装任何分析软件,几条命令就能在 SSH 里完成。

学习建议:按场景记忆,别背参数

很多人学这三个工具觉得难,是因为试图一次性背下所有参数。正确的姿势是按场景记忆:遇到"在日志里找报错"就想起 grep -E 和 -A/-B;遇到"批量改配置"就想起 sed -i.bak;遇到"统计 IP 和状态码"就想起 awk 加 sort、uniq、head 的管道组合。每个工具先掌握五六种高频用法,足以覆盖日常运维的绝大部分需求。

练习材料遍地都是:自己服务器的 Nginx 访问日志就是最好的练习题,每天花几分钟用上面的命令看看访问情况,既能熟悉工具,又能顺带发现异常流量。把这些命令写进 Shell 脚本,配合 crontab 定时执行,就升级成了自动化的日志巡检。文本处理三剑客是 Shell 脚本的基本功,这一关过了,后面写备份脚本、监控脚本都会顺畅很多。

最后提醒一个安全习惯:这三把"刀"都很锋利,在服务器上执行批量修改之前,先想清楚匹配规则会不会误伤。尤其是 sed -i 直接改生产配置时,务必先备份、先在去掉 -i 的情况下试跑一遍看输出是否符合预期;改完 Nginx 配置记得 nginx -t,改完 PHP 配置记得 php -l,语法检查通过再重载服务。宁可多花三十秒验证,也不要等配置改坏、网站 502 了才追悔莫及。

Last modification:September 8th, 2026 at 08:01 am

Leave a Comment