Linux 文本处理工具,这三个词组合在一起,可能第一反应是“这有什么好讲的,不就是 grep、sed、awk 嘛”。但如果你真在服务器上排查过 800MB 的日志文件,被满屏的报错刷到眼花,或者需要从一段接口返回里精确抠出某个字段,你会发现这些看似“古早”的工具,在关键时刻比任何重型监控系统都管用。这篇文章就围绕我在 Linux 下最常用的文本处理思路展开,重点拆解 grep、sed、awk 三件套的核心用法,以及它们怎样组合起来解决真实场景里的日志分析、配置修改、数据统计问题。无论你是刚接触 Linux 的运维新人,还是写了两年脚本但总在正则上踩坑的后端工程师,这里的实操细节都能直接拿来用。
1. 先搞清楚文本处理到底在解决什么
1.1 文本处理不是“文本编辑”
很多刚入行的朋友会把文本处理和 vim、nano 之类的编辑器混为一谈,认为“处理文本就是打开文件改一改”。其实在 Linux 的运维和开发场景里,文本处理更多地指向批量、自动化、可复现地对文本内容进行筛选、提取、替换、统计。比如你有 10 万个请求日志,要求统计每个接口的平均响应时间;或者一个配置文件里有上百个旧 IP 地址,需要一次性替换成新地址。这种任务如果靠人眼打开文件一行一行去看,既不现实也不优雅。
这里就要引入一个核心概念:文本流。Linux 的哲学是一切皆文件,而文件在命令行世界里通常是按行读取的。grep、sed、awk 这类工具本质上都是“按行处理文本”的流式工具,它们读入一行、处理一行、输出一行,不会把整个文件一次性塞进内存。这也是为什么它们能轻松应对 GB 级日志文件的原因——内存占用可控,性能稳定。
1.2 工具三件套的分工逻辑
在 Linux 文本处理工具里,最核心的三个命令是 grep、sed、awk,它们是所有高级玩法的基础。
- grep:负责“找”,按正则表达式筛选出匹配的行或记录。
- sed:负责“改”,按行对文本做替换、删除、插入、打印等流式编辑操作。
- awk:负责“算”,按字段(列)切分文本,支持条件判断、循环和内置函数,能做统计汇总。
举个生活化类比:把文本文件想象成一条流水线上的零件,grep 是质检员,负责把不合格的零件挑出来扔掉,只保留符合标准的;sed 是修理工,照着图纸把零件上错的部分替换掉、删掉或者补上新零件;awk 是数据员,把零件拆开测量每一个参数,统计尺寸分布、计算废品率。三者各管一段,组合起来几乎能覆盖所有文本处理需求。
1.3 适用场景与目标读者
这篇文章的内容围绕“Linux 常用命令中的文本处理工具”展开,既包括最基本的命令格式,也会涉及正则在 shell 中的转义细节、awk 的字段分隔原理、多工具组合实现一个完整日志分析的案例。适合以下人群参考:
- 刚接触 Linux 的新手,想知道除了 ls、cd 之外还有哪些必须掌握的命令;
- 运维工程师,需要快速分析 nginx 日志、系统日志,或批量修改配置文件;
- 后端开发者,想在本地调试时快速提取接口参数或排查异常堆栈;
- 嵌入式开发者,在交叉编译环境里需要处理编译日志和配置脚本。
我接下来分享的内容,前提是大家已经能正常登录 Linux 机器,并具备最基本的命令执行经验。如果你连cd /var/log都还不熟,建议先花半小时把目录切换和 ls 查看玩明白再来读这篇。
2. 动手前的准备:环境与测试数据
2.1 环境要求
在开始写命令之前,先确认环境。绝大多数 Linux 发行版默认已经安装了 grep、sed、awk,不需要额外步骤。你可以用一条命令验证版本:
grep --version | head -1 sed --version | head -1 awk --version | head -1如果提示 command not found,多半是精简安装或容器环境。可以通过系统包管理器安装:Debian/Ubuntu 用apt install grep sed gawk,CentOS/Rocky 用yum install grep sed gawk。我自己常用的 awk 是 gawk(GNU awk),它比 mawk 功能更全,对 UTF-8 中文支持也更友好,强烈建议在 Debian 系环境里安装 gawk。
2.2 准备一份测试日志
实际操作时最好有一份不太大但足够真实的日志文件。下面我直接给一段命令,在/tmp下生成一个模拟 nginx 访问日志,里面包含不同状态码、不同接口、不同 IP,方便后续各种验证:
mkdir -p /tmp/text-lab && cd /tmp/text-lab cat > access.log << 'EOF' 192.168.1.10 - - [10/Oct/2024:13:55:36 +0800] "GET /api/login HTTP/1.1" 200 532 "curl/7.68.0" 192.168.1.11 - - [10/Oct/2024:13:56:01 +0800] "POST /api/order HTTP/1.1" 500 120 "-" "Mozilla/5.0" 192.168.1.12 - - [10/Oct/2024:13:56:22 +0800] "GET /static/index.css HTTP/1.1" 304 0 "Mozilla/5.0" 192.168.1.10 - - [10/Oct/2024:13:57:09 +0800] "GET /api/user/info HTTP/1.1" 200 891 "Mozilla/5.0" 192.168.1.13 - - [10/Oct/2024:13:58:44 +0800] "GET /api/login HTTP/1.1" 404 211 "Wget/1.20" 192.168.1.14 - - [10/Oct/2024:14:01:33 +0800] "GET /api/order/list HTTP/1.1" 200 1024 "Mozilla/5.0" 192.168.1.11 - - [10/Oct/2024:14:02:18 +0800] "POST /api/order HTTP/1.1" 200 88 "Mozilla/5.0" 192.168.1.15 - - [10/Oct/2024:14:03:05 +0800] "GET /api/login HTTP/1.1" 500 0 "-" "curl/7.68.0" EOF这份日志虽然只有 8 行,但字段结构完整:IP、时间、请求方法、路径、协议、状态码、字节数、User-Agent。后续调用的所有命令都能在这个基础上复现。你完全可以自己再加 200 行甚至更多,处理逻辑是一样的。
2.3 先学会用文档和帮助
在临时环境里试命令,最忌讳“背参数”。Linux 的命令参数太多,没有人能全记住。正确的学习方式是:
man grep man sed man awk这三个命令的手册都很长,但不必一次读完。我的建议是,只关注 SYNOPSIS 和 DESCRIPTION 的前两段,剩下的在实际使用时通过/关键字去搜索。比如想知道 sed 怎么用正则替换,在 man 页面里输入/substitute就能直接定位到 s 命令的讲解。这个方法效率比刷文档高得多。
3. grep:能“找”出问题,才算入门
3.1 grep 的核心原理与三种模式
grep 这个名字来自global search regular expression and print,它的核心就是按正则匹配,输出匹配成功的行。使用时有三种常用模式:
grep 'pattern' file # 普通模式,固定字符串匹配 grep -E 'pattern' file # 扩展正则,常见于复杂匹配 grep -P 'pattern' file # perl 兼容正则,可选有人会问:普通模式为什么要加-E呢?因为 grep 默认使用的是基础正则(BRE),很多符号含义受限。比如在 BRE 里,+并不是“匹配一次或多次”的意思,而是一个普通字符;只有加了-E才会变成扩展正则可以识别的量词。所以,只要正则里出现了+、?、|、()这些符号,直接上-E最省心。
实际工作中,我非常建议把-E当一个默认习惯用。比如从日志里找出所有状态码为 500 或 502 的请求:
grep -E '" (500|502) ' /tmp/text-lab/access.log注意我用了双引号和末尾空格来限定状态码字段,避免把 5003 之类也匹配进去。这种“限定边界”的习惯很重要,否则很容易把不该匹配的行捞出来。
3.2 实战:从 nginx 日志里提取指定状态码的 IP
回到刚才的测试日志。我想知道“哪些 IP 产生了 500 错误”,先筛选错误行,再提取 IP。第一步很简单:
grep ' 500 ' /tmp/text-lab/access.log这个空格写法是为了匹配“状态码 500”而不是“字节数 500”。第二步是提取 IP,我会配合-o选项把精确匹配的部分单独输出:
grep -E ' 500 ' /tmp/text-lab/access.log | grep -oE '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'第一条 grep 找错误行,第二条 grep 从错误行开头提取 IPv4 地址。这里-o的用处是只输出正则匹配到的部分,而不是整行,非常适合“从行里抠字段”的场景。执行后得到两个 IP:192.168.1.11和192.168.1.15。
3.3 高频选项与性能注意点
除了-E、-o,还有几个选项几乎每天都要用到:
-v:反向匹配,输出不匹配的行。看日志时最常用,比如排除调试信息grep -v 'DEBUG'。-c:只统计匹配行数。比如统计错误数量grep -c ' 500 ' access.log。-n:显示行号。排查配置错误时能直接定位到第几行。-i:忽略大小写。搜索 ERROR、Error、error 时可统一匹配。-l:列出包含匹配内容的文件名。在多个文件里搜关键词时特别高效。--include:限定文件类型。比如grep -r 'root' /etc --include='*.conf'只在 conf 文件里搜索。
关于性能,我踩过一个坑。需要在大量日志文件中搜索时,不要直接cat *.log | grep xx,而是用grep -r配合多个文件参数,让它自己递归扫描,省掉一次多余的文件读取:
grep -rn --include='*.log' 'ERROR' /var/log/app/另外要留意:grep 适合“找行”,不适合“按字段统计”。如果只是筛选出符合某种模式的行,grep 是最快的;但如果需要对筛选结果做字段求和、去重统计,就不必硬用 grep 在输出上拼凑,而是把它和 awk、sort、uniq 组合起来。这个组合思路后面会专门讲到。
3.4 grep 常见坑:正则符号在 shell 里的转义
新手最容易犯的错,是把正则和 shell 通配符混在一起用。比如要匹配日志文件里所有以.log结尾的行,有人会写:
grep '*.log' access.log这里*在正则里表示“前一个字符重复 0 次或多次”,所以*.log实际匹配的是“任意个*字符后接任意字符再接 log”,效果完全不是你想的*通配。正确的写法是把.转义成字面量:
grep '\.log' access.log同理,搜索带引号的内容时,"在 shell 里会被当成字符串边界,最好用单引号包裹正则,避免 shell 先做变量展开和转义解读。比如匹配包含双引号的请求行,直接写grep '"GET" access.log是可以的,但如果你用的是双引号包裹正则,里层双引号就得写成\":
grep '"GET ' access.log # 单引号包裹,安全 grep "\"GET " access.log # 双引号包裹,需要转义我不建议大家记什么“到底该几个反斜杠”,最简单的方式就是:正则尽量用单引号包起来,如果正则内部还需要单引号字符,再单独处理。
4. sed:流编辑器,按行做“增删改”
4.1 sed 的工作流程
grep 只负责“挑”,想对文本内容做替换、删除、插入,就要请出 sed 了。sed 是一种流编辑器,它不会直接修改源文件,而是把输入流逐行读入内存,执行你给出的命令后,把处理结果输出到标准输出。默认情况下源文件是安全的,除非你用了-i选项。
这个“逐行处理”的机制特别重要,决定了 sed 写法的思考方式:你不是“针对某个文件改”,而是“对每一行判断是否命中规则,命中就做动作,没命中就原样输出”。用命令行演示最直观:
sed 's/200/999/' /tmp/text-lab/access.log这条命令里s是“替换”动作,格式是s/旧内容/新内容/。它把每一行中第一次出现的200换成了999,但文件本身没变。这只是 sed 的一个最小例子。
4.2 地址匹配与动作组合
sed 真正强大的地方在于地址匹配。语法是:
sed '地址动作' file地址可以是一行号、一个范围、一个正则。组合起来可以做许多精确操作:
sed -n '2p' access.log # 只打印第 2 行,-n 禁止默认输出 sed -n '2,4p' access.log # 打印第 2 到 4 行 sed -n '/500/p' access.log # 打印包含 500 的行 sed '/500/d' access.log # 删除包含 500 的行 sed '1,3d' access.log # 删除第 1 到 3 行 sed 's/192.168.1.10/10.0.0.1/' access.log # 替换 IP这里要说一下-n的配合逻辑。默认 sed 会打印所有行,即使你执行d删除动作后,其他行也会照常输出。如果你只想看被匹配到的行,就必须用-n抑制默认输出,再配合p命令显式打印目标行。
实际使用时我经常把地址范围跟正则搭配:
sed -n '/2024:13:55/,/2024:14:02/p' /tmp/text-lab/access.log这条命令会从匹配“13:55”的行开始打印,直到匹配“14:02”的行结束,非常适合按时间段截取日志片段。这个技巧在日志分析里相当实用,比用 grep 一条条匹配效率高很多。
4.3 实战:批量替换配置文件里的 IP 和端口
运维工作中最常见的需求,是把一套环境的配置批量移植到另一套环境。比如一个配置目录下有几十个application.yml,里面写了旧 IP192.168.1.10和端口8080,要换成新 IP10.12.5.8和新端口9090。用 sed 可以一条命令完成全目录替换:
find /etc/myapp -name '*.yml' -exec sed -i 's/192\.168\.1\.10/10.12.5.8/g; s/8080/9090/g' {} \;这里我用了两个关键点:
s/旧/新/g中的g表示“每一行所有匹配都替换”,不加的话只替换每行第一次出现的位置;-i后面接没有备份后缀,表示直接写回原文件。稳妥来说,我建议写成-i.bak,这样 sed 会在修改前复制一份.bak备份文件,出问题时能快速回滚。
为什么正则里的点要写成\.?因为在正则里.是“匹配任意字符”的通配符,如果不转义,192.168.1.10可能把192x168y1z10也会匹配上。这种时候宁可多写两个反斜杠,也不要省。
4.4 sed -i 的安全操作与备份习惯
关于-i我想专门多说几句。我身边的同事好几次因为忘了备份,一条sed -i把线上配置改错,整夜都在回滚。所以我的习惯是:
sed -i.bak 's/old_ip/new_ip/g' /etc/nginx/nginx.conf这样会在同目录生成nginx.conf.bak。确认改动无误后,再决定是否删除备份。另一个安全习惯是先不带-i跑一遍,观察输出是否符合预期,确认无误后再加-i执行。
如果配置文件里包含中文注释,用 sed 替换英文内容通常没问题,但如果你要替换的段落跨越行或者包含特殊符号(如&、/等),很容易踩坑。比如替换内容里包含/,分隔符就会被错误解释。解决办法是换用另一个分隔符,比如#:
sed -i 's#/old/path#/new/path#g' /etc/some.conf这个技巧就叫“换分隔符”,记住了能少掉很多头发。
5. awk:按列统计,文本处理的天花板
5.1 awk 的分行分列模型
awk 与 grep、sed 的最大不同,在于它默认按**空白字符(空格/Tab)**把每一行切分成多个字段。$0代表整行,$1代表第一个字段,$2代表第二个字段,以此类推。这种模型用来处理“每一列有明确含义”的文本非常顺手。
比如我们测试日志里,$1是 IP,$4是时间,$6是请求方法,$7是请求路径,$9是状态码,$10是字节数。直接用awk '{print $1}'就能把 IP 列全部打印出来:
awk '{print $1}' /tmp/text-lab/access.logawk 还允许自定义字段分隔符。-F参数配合正则,可以处理 CSV、日志等非空白分隔的数据。比如解析/etc/passwd,它是冒号分隔的:
awk -F: '{print $1, $3}' /etc/passwd这条命令同时打印用户名和 UID,是系统管理里的高频操作。
5.2 BEGIN/END 和 pattern {action} 结构
awk 的完整语法格式是:
awk 'BEGIN{初始化动作} pattern{逐行动作} END{收尾动作}'BEGIN块在处理任何输入行之前执行,常用于定义变量、打印表头;pattern {action}是逐行处理的核心,只有条件匹配时才执行动作;END块在所有行处理完毕后执行,常用于输出汇总结果。
光看结构可能觉得抽象,用求和统计马上就能理解。统计一下日志中状态码 200 的请求一共多少字节:
awk '$9 == 200 {sum += $10; count++} END {print "count:", count, "bytes:", sum}' /tmp/text-lab/access.log这里$9 == 200是 pattern,表示只处理第 9 列为 200 的行;{sum += $10; count++}是动作,对字节数累加;END最后把统计结果打印出来。awk 内部不需要管变量是否已定义,默认值就是数字 0 或空字符串。
5.3 实战:统计接口平均响应时间、按 IP 聚合流量
下面用一个真实场景把 awk 的能力串起来。假设你的 nginx 日志里记录了每个请求的响应时间,字段在$NF(最后一个字段),你想按接口路径统计平均耗时和请求次数:
awk '{path[$7]++; sum[$7]+=$NF} END {for (p in path) print p, path[p], sum[path]/path[p]}' access.log这条命令需要用一段带响应时间的日志来测,原理是:
path[$7]++建立以“第 7 列路径”为 key 的请求次数计数器;sum[$7]+=$NF把每个请求的响应时间累加到对应的路径 key 下;END里遍历所有路径,输出次数和平均值。
这个模式是 awk 做聚合分析的核心套路,往上套业务几乎通用。按 IP 聚合流量也是同一个思路,只要把 key 换成$1即可:
awk '{ip[$1]++; bytes[$1]+=$10} END {for (i in ip) print i, ip[i], bytes[i]}' /tmp/text-lab/access.log | sort -k3 -nr加上sort -k3 -nr后,结果会从流量最大的 IP 往下排列,一眼就能看出谁在“吃”带宽。
5.4 awk 与 sed/grep 的搭档玩法
三个工具组合起来,能解决很多看似复杂的任务。比如我想提取访问/api/login的 500 请求率,可以先用 grep 筛出该接口的日志,再用 awk 统计:
grep '/api/login' /tmp/text-lab/access.log | awk '{total++; if ($9 >= 500) bad++} END {print "total:", total, "bad:", bad+0, "rate:", (bad/total*100)"%"}'这里bad+0是为了在 bad 未初始化时输出0而不是空值。(bad/total*100)算出百分比。三条命令的组合比单独用任何一个都要灵活,也是我实际排查问题最常用的方式。
6. 多工具组合:一套完整的日志分析实操
6.1 场景设定
纸上谈兵讲完了,还是用一份真实的 nginx 请求日志把整个流程走一遍。职责是:找出最近一天访问量最高的 Top 5 接口、各接口平均耗时、以及 5xx 错误的分布。这是日志分析里最经典的需求之一。
环境还是用刚才生成的/tmp/text-lab/access.log。先直接跑一个综合脚本:
cat /tmp/text-lab/access.log | awk '{print $7, $NF, $9}' | grep -v '/static' > /tmp/text-lab/result.txt这里我把每行精简成“路径 耗时 状态码”三列,排除了静态资源。但这一步有多余——awk 本身就能过滤字段值,如果路径是第 7 列且等于/static,直接用 pattern 排除更干净:
awk '$7 !~ /\/static/ {print $7, $NF, $9}' /tmp/text-lab/access.log > /tmp/text-lab/result.txt这个写法用!~表示“不匹配”。注意正则里/需要转义,写成\/static。养成“能用 awk 过滤就不过多起管道”的习惯,能省去很多中间管道开销。
6.2 统计 Top 5 接口
拿到精简结果后,用 sort 和 uniq 统计路径出现次数:
awk '{print $1}' /tmp/text-lab/result.txt | sort | uniq -c | sort -nr | head -5这里的逻辑是:
awk '{print $1}'把路径列提取出来;sort排序,保证相同的路径相邻排列;uniq -c统计连续相同行的数量;sort -nr按数字倒序排列;head -5取前五。
执行结果可以直观看到哪个接口被调用最多。这里要注意uniq -c只能统计相邻重复行,如果文件没有被 sort 到相邻,统计结果会分成多行,所以必须先 sort 再 uniq。
6.3 统计每个接口的平均耗时
继续用结果文件,按接口名聚合平均耗时:
awk '{sum[$1]+=$2; cnt[$1]++} END {for (i in sum) print i, sum[i]/cnt[i], cnt[i]}' /tmp/text-lab/result.txt | sort -k2 -nr这份统计里第 1 列是路径,第 2 列是耗时,第 3 列是请求次数。sort -k2 -nr表示按第二列数字倒序排列,能看出哪些接口耗时最多。如果发现静态资源或某接口响应时间异常高,再单独用 grep 拉出该路径的样本行,查看具体请求细节。
6.4 定位 5xx 错误分布
错误分布用一条 awk 就能搞定:
awk '$3 >= 500 {print $1, $2}' /tmp/text-lab/result.txt | sort | uniq -c但我们要的不只是数量,最好能看出是哪个 IP 触发的。回到原始日志去关联:
awk '$9 >= 500 {print $1, $7}' /tmp/text-lab/access.log | sort | uniq -c这个输出把 IP、接口、错误次数列出来,可以快速锁定“哪个 IP 在反复打某个接口导致 5xx”。如果需要更完整的上下文,可以再 grep 出这些 IP 的全部日志,用 sed 或者 head/tail 截取时间范围。
6.5 把流程写成小脚本
多次操作之后,我发现把这些命令存在一个 shell 脚本里非常值。以后每次排查看日志,直接跑一句脚本,不用重新敲命令:
#!/bin/bash LOG=${1:-/var/log/nginx/access.log} echo "Top 10 interfaces:" awk '{print $7}' "$LOG" | sort | uniq -c | sort -nr | head -10 echo "" echo "5xx error distribution:" awk '$9 >= 500 {print $1, $7}' "$LOG" | sort | uniq -c | sort -nr echo "" echo "Response time top 10:" awk '{print $7, $NF}' "$LOG" | awk '{if ($2 ~ /^[0-9.]+$/) print}' | sort -k2 -nr | head -10这里第 3 段加入了一个正则判断$2 ~ /^[0-9.]+$/,用来过滤非数值耗时的脏数据,避免 sort 按字符串排序时得到错误顺序。脚本里可以直接用位置参数传日志路径,默认指向 nginx 访问日志,非常实用。
7. 常见问题与排查技巧速查表
7.1 工具输出不显示中文
碰到中文乱码时,大多数情况不是工具本身的问题,而是 locale 环境不对。先检查:
echo $LANG如果输出不是en_US.UTF-8或zh_CN.UTF-8,在命令行临时执行export LANG=en_US.UTF-8再试。另外 grep 匹配中文时,不要用grep '中文' file直接匹配,先确认文件编码,一般 UTF-8 没问题,若是 GBK 编码则需要先转码:
iconv -f GBK -t UTF-8 file.log | grep '中文'7.2 正则匹配不到结果
这个是最常见的问题,通常有四个原因:
| 原因 | 现象 | 解决 |
|---|---|---|
| 正则写错 | 明明字符串在文件里却匹配不到 | 用grep -F做字面量匹配测试 |
| 转义问题 | .匹配了不该匹配的字符 | 需要匹配字面量点号时写成\. |
| 大小写 | 文件里是 ERROR,pattern 写 error | 用-i忽略大小写 |
| 变体编码 | 文件含 CRLF | 先dos2unix转换或用sed -i 's/\r$//' |
排查时最好的调试手段是用grep -o搭配更宽松的正则,逐步缩小范围。比如先确认能否匹配到一个短字符,再扩展成完整模式。
7.3 大文件处理卡顿
服务器上的日志动辄几个 GB,直接cat再管道会白白耗内存。正确姿势是直接用 grep/sed/awk 读取,让它们自己流式处理。如果只是要快速看文件开头,用head;找行数,用wc -l;找某一个模式,用grep -n。避免在管道前面加不必要的cat。
对于几个 GB 文件,还可以用 awk 直接处理,配合NR行号变量定位特定行范围,比装个大编辑工具快得多。比如提取第 1000 到 2000 行:
awk 'NR >= 1000 && NR <= 2000' huge.log另一个方法是用sed -n '1000,2000p' huge.log,两者都可,但 awk 可扩展性更强。
7.4 隐藏字符与编码问题
排查配置时经常遇到“看起来一样却比对不上”的问题。用sed -n 'l' file可以把不可见字符按可见形式展示出来:
sed -n '1l' /tmp/text-lab/access.logl命令会把 Tab 显示成\t,行尾显示成$,方便检查是否有 Windows 换行符。如果发现\r,用sed -i 's/\r$//' file统一清除。
处理 CSV 文件时,我习惯先用file命令确认编码和换行符,避免后面 awk 的-F,解析时被\r干扰:
file data.csv如果输出带with CRLF line terminators,先转一下再处理。
7.5 别忽略流式处理的最小化原则
最后分享一个能提高效率的习惯。多工具组合很强大,但也要避免“无脑起管道”。能在一个 awk 里完成的统计,不要拆成 5 条 grep 加 3 条 sed。管道越多,排查问题越困难,性能也越差。一个实用的判断标准是:如果整条命令超过 3 个管道,大概率可以用 awk 单条实现。
8. 一点个人使用体会
我这些年大量使用 Linux 文本处理工具排查线上问题,最大的感受是:这些命令看起来“古老”,但它们的处理模型非常稳定——按行读入、规则匹配、流式输出,永远不依赖界面和图形环境。SSH 登录上去就能干活,配合脚本还能自动化重复操作。遇到复杂需求时,先用 grep 快速筛选范围,再用 sed 修正文本,最后用 awk 统计聚合,这种“三步走”的思路几乎覆盖了 90% 的运维场景。
如果你刚学,我建议不要盯着满屏参数背,而是把今天文章里的日志分析脚本在真实环境里跑一遍,改一改路径和字段,观察输出变化。真正上手一次,比读十遍理论都管用。最后再提一个小技巧:写命令时尽量用双引号把变量括起来,比如grep "$keyword" file,否则文件路径或关键词里带空格时,命令会突然失效。这些细小的习惯积累起来,就是处理文本时少踩坑的关键。