在Linux环境里做开发和运维,每天逃不开的一件事就是处理文本。不管是看日志、改配置、分析数据,还是写脚本批量处理,本质上都在跟一堆堆字符打交道。手里那点活儿,用鼠标和编辑器挨个翻,能把你累到怀疑人生;可要是你真正用好了grep、sed、awk这三个命令,效率直接翻几倍,而且写出来的Shell脚本会显得特别利落。这篇东西,我打算把这三个工具从底层逻辑讲到实战技巧,把我平时踩过的坑和积累的习惯一并交代清楚,希望给正在入门Shell脚本、或者写了几年脚本但总觉得"差点意思"的朋友一些真正能落地的参考。
先给这三个家伙定个位:grep负责"找",sed负责"改",awk负责"算和整理"。它们不是互相替代的关系,而是各管一段的黄金搭档。一个典型的场景是这样的——你拿到一份几十万行的日志,先grep把报错行筛出来,再用awk提取里面的IP、时间、耗时这些字段,最后用sed把格式整理成你想要的报表。三步走完,原本一上午的活儿,一条命令几秒钟就出结果了。这就是文本处理三件套的价值:把"体力活"变成"脑力活"。
1. 三件套的定位与整体设计思路
1.1 grep、sed、awk分别解决什么问题
很多人刚接触这三个命令时最容易犯的错,就是想用某一个搞定所有需求。实际上它们的定位完全不同。
grep全称是"global regular expression print",它的核心功能是按正则表达式筛选文本行。它像流水线上的质检员:只关心"这一行到底有没有我要的东西",有就留下,没有就丢掉。它不会改你的数据,只是"过筛子"。我平时用grep最多的场景就是日志分析和代码搜索,比如查某个接口什么时候开始报错、某段逻辑在哪个文件里出现过。
sed(stream editor,流式编辑器)的强项是"就地加工"。它能对匹配到的行做替换、删除、插入、追加操作。它像一个装配线上的改造工:经过它手里的每一行,都可能是全新的面貌。配置文件的批量改动是它最经典的用武之地,比如几十台服务器上的Nginx配置要统一改一个参数,手改得改到吐,sed一条命令全部搞定。
awk则是个"重器",它把每一行拆成字段(列),然后支持编程逻辑——变量、循环、判断、数组全都有。它像流水线尽头的数据分析员,把质检员和改造工送过来的数据做统计、汇总、格式化输出。像"统计Nginx日志里访问量Top10的IP""计算所有接口的平均响应时间"这类需求,awk写起来就是几行的事,你要是用Python跑,还得写文件读取、字段Splite,绕一大圈。
1.2 为什么它们是Shell脚本的基石
这三个工具的底层设计哲学,和Unix的经典理念完全一致:一个程序只做好一件事,然后通过管道协作解决复杂问题。一件复杂的文本处理任务,几乎都会被拆成一个管道链,比如:
bash复制cat app.log | grep "ERROR" | awk '{print $2}' | sort | uniq -c
这个管道链里,每个命令只负责一个环节,数据像流水一样经过它们,最后落到你手上。这种设计让Shell脚本拥有极强的组合性和可维护性——你想调整中间任何一环,不需要改别的地方。
还有一点非常重要:三者的执行模型都是逐行处理,也就是流式处理。这意味着不管文件有多大,哪怕几个GB,内存里永远只保留当前这一行,不会因为文件大而撑爆内存。相比之下,你用vim打开一个1GB的文件可能直接卡死,但用grep去扫这个大文件,轻松得很。
所以,对于运维工程师、后端开发、数据分析师来说,这三件套不只是"会几个命令"的问题,它直接决定你处理日常任务的效率上限。说它们是Shell脚本的基石,一点都不夸张。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. grep:文本过滤的精准打击
2.1 从基础匹配到扩展正则的进阶路径
grep看起来简单,实际上常用的几个参数如果拿捏好了,威力完全不一样。先从最基础的开始,看看这段实操中高频出现的组合。
bash复制# 基础字符串匹配,找日志中的ERROR行
grep "ERROR" app.log
# 忽略大小写匹配(日志里可能混着Error、error、ERROR)
grep -i "error" app.log
# 反向匹配:排除含DEBUG的行
grep -v "DEBUG" app.log
# 扩展正则:匹配ERROR、FATAL、WARN三种级别(注意-E参数)
grep -E "ERROR|FATAL|WARN" app.log
# 只输出匹配到的部分,而不是整行(配合-o,是字段提取的利器)
grep -oE "[0-9]+\.[0-9]+\.[0-9]+\
