本文导读本文是系列第 5 篇讲解 Linux 文本处理领域最重要的三个工具grep、sed、awk。Java 开发者排查生产问题时80% 的时间在和日志文件打交道而这三个工具正是日志分析的核心武器。本文会讲透它们的核心用法并结合 AI 推理日志分析给出实战案例。关键词Linux grep sed awk教程、Linux文本处理、grep正则表达式、awk字段处理、sed替换命令、Linux日志分析目录一、为什么 Java 开发者必须掌握这三个工具二、grep文本搜索的第一选择2.1 grep 基础用法2.2 上下文查看排查问题的利器2.3 正则表达式grep 的真正威力2.4 grep 处理二进制文件和大文件的注意事项三、sed流编辑器文本替换的标准工具3.1 sed 的核心用法查找替换3.2 sed 的删除与插入操作3.3 sed 多命令组合与高级用法四、awk结构化文本处理之王4.1 awk 的核心概念字段与分隔符4.2 awk 的条件过滤比 grep 更精确4.3 awk 的统计能力日志分析的核心武器4.4 awk 处理多行记录与字段计算五、三剑客组合实战管道连接威力倍增六、AI 大模型日志分析实战案例七、常见问题解答FAQ❓ Q1grep、sed、awk 应该怎么选有没有简单的判断标准❓ Q2sed 和 awk 都能做替换该用哪个❓ Q3处理几个GB的大日志文件这些工具会不会内存溢出❓ Q4awk 的内置变量太多记不住有没有最常用的几个❓ Q5正则表达式在 grep/sed/awk 里语法一致吗本篇小结与系列导航 参考资料一、为什么 Java 开发者必须掌握这三个工具排查生产问题时你的应用日志文件可能有几十万行传统的打开文件用眼睛找完全不现实。grep、sed、awk 这三个工具分别解决查找、“替换”、结构化处理三类问题组合起来几乎能应对所有文本分析场景。它们的设计理念高度一致都是面向行的流式处理工具逐行读取输入对每一行执行匹配/替换/计算然后输出结果。这种设计使得它们可以通过管道|无缝衔接组合成强大的处理链。理解这一点比死记命令参数更重要。二、grep文本搜索的第一选择2.1 grep 基础用法# 基本语法grep 搜索内容 文件名grepERRORapp.log# 不区分大小写搜索-iignore casegrep-ierrorapp.log# 递归搜索整个目录下所有文件-rrecursivegrep-rOutOfMemoryError/var/log/myapp/# 显示匹配行的行号-nnumber排查问题时定位具体哪一行很有用grep-nERRORapp.log# 反向匹配只显示不包含某内容的行-vinvertgrep-vDEBUGapp.log# 统计匹配的行数而不显示内容-ccountgrep-cERRORapp.log# 只显示匹配到的部分不显示整行-oonly matchinggrep-ouser_id[0-9]*access.log2.2 上下文查看排查问题的利器排查异常时仅看到报错那一行往往信息不足需要看报错前后的上下文# 显示匹配行及其后 5 行-Aaftergrep-A5OutOfMemoryErrorapp.log# 显示匹配行及其前 5 行-Bbeforegrep-B5Connection refusedapp.log# 同时显示前后各 3 行-Ccontextgrep-C3NullPointerExceptionapp.log# 实战场景查看异常堆栈的完整信息# Java 的异常堆栈通常跨越多行只看匹配行本身看不到完整堆栈grep-A20Exception in threadapp.log 生产提示排查 Java 异常时grep -A 20 Exception这类命令是查看完整堆栈信息的标准做法。因为 Java 异常堆栈stack trace往往有几十行光看grep Exception匹配到的那一行根本看不出问题出在哪个调用链上。习惯了用-A参数后排查效率会明显提升。2.3 正则表达式grep 的真正威力grep默认支持基础正则表达式BRE加-E参数后支持扩展正则表达式ERE更接近大多数编程语言的正则语法。# 用 -E 启用扩展正则推荐语法更直观等同于 egrep 命令grep-EERROR|WARNapp.log# 匹配 ERROR 或 WARN不加-E需要用 \| 转义# 匹配 IP 地址简化版本实战中够用grep-E[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}access.log# 匹配特定时间范围的日志比如 2026-06-30 的 10 点到 12 点grep-E2026-06-30 1[0-2]:app.log# 匹配以特定字符串开头/结尾的行^ 表示行首$ 表示行尾grep^2026-06-30app.log# 以这个日期开头的行greptimeout$app.log# 以 timeout 结尾的行# 匹配多个文件并显示是哪个文件匹配的grep-rnOutOfMemoryError/var/log/myapp/*.log⚠️ 踩坑记录grep默认的基础正则表达式BRE里、?、|、(、)等元字符需要用反斜杠转义才能生效比如grep ERROR\|WARN这和大多数编程语言里正则表达式的习惯不一样容易写错导致匹配不到任何内容却不报错。建议养成习惯永远用-E参数或直接用egrep命令这样正则语法和你熟悉的 Java 正则、Python 正则基本一致不容易踩坑。2.4 grep 处理二进制文件和大文件的注意事项# 在不确定文件类型的目录里递归 grep 时二进制文件可能导致输出乱码或卡顿# 用 -I 跳过二进制文件大写 I等同于 --binary-fileswithout-matchgrep-rIERROR/var/log/myapp/# 对于超大文件几个GB的日志grep 配合管道流式处理不会一次性加载整个文件到内存# 这是 grep 的天然优势不用担心大文件导致内存溢出grepERRORhuge_access.log|wc-l# 结合 zgrep 直接搜索压缩日志不需要先手动解压zgrepERRORapp.log.gz三、sed流编辑器文本替换的标准工具sedStream Editor是非交互式的文本编辑工具最常见的用法是批量替换文本内容。3.1 sed 的核心用法查找替换# 基本语法sed s/查找内容/替换内容/ 文件名# s 表示 substitute替换三个斜杠分隔三部分# 默认只在终端显示替换结果不修改原文件用于先预览效果seds/ERROR/WARNING/app.log# 默认只替换每行第一个匹配项加 gglobal才会替换该行所有匹配项seds/ERROR/WARNING/gapp.log# -i 直接修改原文件in-place没有这个参数不会真正修改文件sed-is/127.0.0.1/192.168.1.100/gapplication.yml# -i.bak修改前自动创建备份强烈推荐比直接 -i 安全得多sed-i.baks/old-domain.com/new-domain.com/gnginx.conf# 只替换指定行号范围内的内容比如只替换第 10-20 行sed10,20s/DEBUG/INFO/gapp.log# 只替换匹配特定模式的行比如只替换包含 production 的行里的内容sed/production/s/DEBUG/INFO/config.yml⚠️ 踩坑记录sed -i直接修改原文件且没有确认提示这是一个高风险操作。强烈建议永远用sed -i.bak而不是裸的sed -i多打几个字符的成本换来的是误操作后能立刻恢复的安全网。另外要注意macOS 自带的 sedBSD 版本和 Linux 的 GNU sed 在-i参数的语法上不兼容——GNU sed 的-i.bak和 BSD sed 的-i .bak有空格写法不同如果你的部署脚本要跨平台运行这里很容易因为平台差异导致脚本报错或者意外不生效。3.2 sed 的删除与插入操作# 删除指定行ddeletesed5dapp.log# 删除第5行sed5,10dapp.log# 删除第5到10行sed/DEBUG/dapp.log# 删除所有包含 DEBUG 的行清理日志常用# 删除空行sed/^$/dconfig.yml# 在指定行前/后插入内容sed3i\新插入的行app.log# 在第3行之前插入(iinsert)sed3a\新插入的行app.log# 在第3行之后插入(aappend)# 实战批量清理日志中的 DEBUG 级别日志行只保留 INFO 及以上级别sed-i.bak/\[DEBUG\]/dapplication.log3.3 sed 多命令组合与高级用法# 用 -e 执行多个 sed 命令一次性完成多项替换sed-es/ERROR/WARNING/g-es/INFO/NOTICE/gapp.log# 用分号分隔多个命令效果等同于多个 -eseds/ERROR/WARNING/g; s/INFO/NOTICE/gapp.log# 使用正则表达式进行复杂替换结合分组引用 \1 \2# 把 keyvalue 格式转换成 valuekey交换位置echonamezhangsan|sed-Es/([a-z])([a-z])/\2\1/# 输出zhangsanname# 实战场景批量修改 Spring Boot 配置文件中的端口号sed-i.baks/server.port: 8080/server.port: 8081/application.yml# 实战场景脱敏处理日志中的手机号保留前3位后4位中间用*代替sed-Es/([0-9]{3})[0-9]{4}([0-9]{4})/\1****\2/gaccess.log 生产提示处理涉及用户隐私信息的日志手机号、身份证号、邮箱时sed 配合正则表达式做脱敏处理是常见的合规需求。上面手机号脱敏的例子可以直接用在日志归档或者把日志提供给第三方分析前的预处理环节避免敏感信息泄露。四、awk结构化文本处理之王awk比grep和sed更强大它把每一行看作由多个字段组成的记录特别适合处理表格化、结构化的文本比如 Nginx access log、CSV 文件。4.1 awk 的核心概念字段与分隔符# awk 默认用空格或连续空白作为字段分隔符$1 表示第1个字段$2 表示第2个字段# $0 表示整行内容NF 表示当前行的字段总数# 示例数据一行典型的 Nginx access log# 192.168.1.1 - - [30/Jun/2026:10:00:00 0800] GET /api/users HTTP/1.1 200 1234# 打印第1个字段IP地址awk{print $1}access.log# 打印第1个和第7个字段IP地址和请求路径awk{print $1, $7}access.log# 打印最后一个字段用 $NFNF是字段总数的内置变量awk{print $NF}access.log# 自定义分隔符-F 参数处理 CSV 或自定义格式日志echoname,age,city|awk-F,{print $2}# 输出age4.2 awk 的条件过滤比 grep 更精确# 只处理满足条件的行类似 grep但能结合字段位置精确过滤# 找出所有返回状态码为 500 的请求假设状态码是第9个字段awk$9 500 {print $0}access.log# 找出响应时间超过 1000ms 的慢请求假设响应时间是最后一个字段awk$NF 1000 {print $1, $7, $NF}access.log# 字符串匹配过滤~ 表示匹配正则awk$7 ~ /^\/api\/user/ {print $0}access.log# 组合多个条件 表示且|| 表示或awk$9 500 $7 ~ /^\/api/ {print $1, $7}access.log4.3 awk 的统计能力日志分析的核心武器# 统计访问次数最多的 IP这是排查异常流量/攻击的经典命令awk{print $1}access.log|sort|uniq-c|sort-rn|head-10# 用 awk 自带的累加统计统计每个状态码出现的次数awk{count[$9]} END {for (code in count) print code, count[code]}access.log# 统计总流量假设响应大小是第10个字段单位字节awk{total $10} END {print Total bytes:, total}access.log# 计算平均响应时间awk{sum $NF; n} END {print Average response time:, sum/n, ms}access.log# 输出格式化报表结合 printf 让输出更整齐awk{count[$9]} END {for (code in count) printf 状态码 %s: %d 次\n, code, count[code]}access.log 生产提示awk {print $1} access.log | sort | uniq -c | sort -rn | head -10这条命令是排查流量异常和潜在攻击的标准武器——它统计出访问次数最高的 10 个 IP。如果发现某个 IP 在短时间内的请求量异常高远超正常用户行为很可能是爬虫、压测工具或者恶意攻击可以结合这个结果进一步用防火墙规则封禁。这条命令组合值得直接记下来。4.4 awk 处理多行记录与字段计算# 计算每行字段数NF快速发现格式不规整的日志行awk{print NF, $0}app.log|sort-n|head-5# BEGIN 和 END 块在处理数据前后执行的特殊逻辑awkBEGIN {print 开始分析日志 } {count} END {print 总行数:, count}app.log# 实战分析 AI 推理服务日志提取每次请求的 token 消耗# 假设日志格式[2026-06-30 10:00:00] request_idabc123 prompt_tokens150 completion_tokens80awk-F[ ]{for(i1;iNF;i) if($iprompt_tokens) prompt$(i1); if($icompletion_tokens) completion$(i1)} END {print 总prompt tokens:, prompt, 总completion tokens:, completion}inference.log五、三剑客组合实战管道连接威力倍增grep、sed、awk 单独使用已经很强大组合起来威力更大。以下是几个真实生产场景的组合命令# 场景1从大日志文件中筛选出某个时间段的 ERROR 日志并统计每种错误类型的数量grep2026-06-30app.log|grepERROR|awk-FERROR: {print $2}|awk-F at {print $1}|sort|uniq-c|sort-rn# 场景2找出某个用户ID相关的所有日志脱敏处理后导出grepuser_id10086app.log|sed-Es/(phone)[0-9]{7}([0-9]{4})/\1*******\2/guser_10086_filtered.log# 场景3分析 Nginx 日志找出哪些接口的 5xx 错误最多典型的故障定位流程awk$9 500 {print $7}access.log|sort|uniq-c|sort-rn|head-20# 场景4实时监控日志中的异常结合 tail -f 实现实时报警雏形tail-f/var/log/myapp/app.log|grep--line-bufferedERROR|whilereadline;doecho检测到错误:$line# 这里可以加发送告警通知的逻辑企业微信/钉钉webhookdone⚠️ 踩坑记录上面场景4里的grep --line-buffered容易被忽略但很关键。grep默认在处理管道输出时会做缓冲buffer等缓冲区积累到一定数据量才会往下游输出这在配合tail -f做实时监控时会导致明显的延迟看起来像卡住了实际是数据攒在缓冲区里没及时往后传。加上--line-buffered参数后grep 会按行立即输出配合tail -f才能实现真正的实时监控效果。六、AI 大模型日志分析实战案例结合系列主题给出一个分析 AI 推理服务日志的完整案例。假设 vLLM 或 Ollama 服务的日志格式包含请求耗时、token 数量等信息# 示例日志格式简化# [2026-06-30T10:15:23] modelqwen2.5-7b latency_ms850 prompt_tokens120 completion_tokens300 statussuccess# 1. 统计当天推理请求的总数和成功率total$(grep2026-06-30inference.log|wc-l)success$(grep2026-06-30inference.log|grepstatussuccess|wc-l)echo总请求数:$total, 成功率:$(awkBEGIN{printf\%.2f%%\,$success/$total*100})# 2. 计算平均推理延迟latency_msgrep2026-06-30inference.log|awk-Flatency_ms{split($2,a, ); suma[1]; n} END {print 平均延迟:, sum/n, ms}# 3. 找出延迟超过 2000ms 的慢请求用于排查性能问题grep2026-06-30inference.log|awk-Flatency_ms{split($2,a, ); if(a[1]2000) print $0}# 4. 统计每个模型的 token 吞吐量用于评估 GPU 资源利用率awk-Fmodel| latency_ms| prompt_tokens| completion_tokens\{split($2,m, ); models[m[1]] $4$5} END {for (mod in models) print mod, models[mod], tokens}inference.log这套命令组合可以在没有专门搭建监控系统PrometheusGrafana后续第 27 篇会讲之前快速对 AI 推理服务的运行状况做出基本判断是排查问题的第一道工具。七、常见问题解答FAQ❓ Q1grep、sed、awk 应该怎么选有没有简单的判断标准简单判断只是查找用 grep需要替换/删除文本内容用 sed需要按字段做统计、计算、复杂逻辑处理用 awk。三者经常组合使用先用 grep 缩小范围再用 awk 做精细分析。❓ Q2sed 和 awk 都能做替换该用哪个简单的全文替换用 sed 更简洁一行命令解决如果替换逻辑依赖字段位置或复杂计算比如把第3个字段的值乘以2awk 更合适因为它对字段的处理能力比 sed 强得多。❓ Q3处理几个GB的大日志文件这些工具会不会内存溢出不会。grep、sed、awk 都是流式处理工具逐行读取处理不会把整个文件加载进内存这是它们相比用编程语言写脚本读取整个文件到内存处理的天然优势处理任意大小的文件内存占用都基本恒定。❓ Q4awk 的内置变量太多记不住有没有最常用的几个最高频的几个$0整行、$1-$N各字段、NF字段总数、NR当前行号、FS字段分隔符、OFS输出字段分隔符。掌握这几个基本能应对大部分场景更复杂的功能用到时再查手册即可。❓ Q5正则表达式在 grep/sed/awk 里语法一致吗不完全一致。grep 默认是基础正则BRE加-E后是扩展正则EREsed 默认也是 BRE加-E或-r启用 EREawk 默认就支持 ERE 风格的正则不需要额外参数。建议统一习惯处理 grep 和 sed 时都加-E参数这样三个工具的正则语法基本就统一了减少记忆负担。本篇小结与系列导航 核心结论grep、sed、awk 是 Linux 文本处理的三大支柱分别负责查找、替换、结构化统计三者都是逐行流式处理可处理任意大小文件而不会内存溢出。grep 配合-A/-B/-C上下文参数是排查 Java 异常堆栈的标准做法sed 修改文件务必配合-i.bak防止误操作awk 的字段统计能力结合 sort/uniq是日志分析、流量统计、AI 推理性能分析的核心武器三者通过管道组合能解决绝大多数文本分析需求。 参考资料GNU grep 官方手册GNU sed 官方手册GNU awk 官方手册正则表达式在线测试工具 regex101如果本文对你有帮助请点赞 收藏 ⭐ 支持一下欢迎在评论区留言交流。系列标签Linuxgrepsedawk文本处理日志分析正则表达式Java运维