Linux日志分析实战:从grep、awk到sed的文本处理全攻略
系列写到第九篇这次我想聊聊日志分析和文本处理相关的那几个命令。前面几篇我们把文件、权限、进程、磁盘、网络都过了一遍但很多朋友在实际干活时仍然觉得不够用尤其是系统出了问题需要翻日志的时候那种“每个命令都认识组合起来却无从下手”的感觉特别明显。这篇我把日志查看、内容过滤、字段提取、统计汇总这一套完整串起来看完你就能用纯命令行把几百MB甚至几个GB的日志文件理出清晰线索找出报错根源顺带还能统计出业务指标。适合刚接触服务器运维的新手也适合写了些脚本但总在日志处理上卡壳的同学。1. 日志文件在哪里系统日志的常见路径与格式解析1.1 别乱翻先从系统的日志目录开始很多同学一上来就find / -name *.log结果找出一堆跟自己无关的文件浪费时间还容易被干扰。传统Linux系统日志集中在/var/log/目录这是约定俗成的规矩绝大部分软件都会把日志丢在这里。我最常用的是这几个/var/log/messages系统整体运行信息包括内核、服务启动、认证等信息。有些发行版改成了/var/log/syslog。/var/log/secure认证与安全日志SSH登录失败、sudo授权记录都会出现在这里。排查暴力破解基本就靠它。/var/log/cron定时任务执行记录任务没跑或者跑出错先来这里看。/var/log/dmesg内核环形缓冲区日志硬件认不认、驱动报不报错都在这。除了这些系统级日志各种应用通常在自己安装目录或/var/log/下建子目录比如Nginx写/var/log/nginx/access.log和error.logMySQL写/var/log/mysql/error.log。建议先ls /var/log/看一下这个目录里都有什么心里有数别一上来就全局搜索。1.2 日志格式与字段含义日志为什么难看懂因为没有统一标准。但绝大多数日志都是“时间 来源 事件描述”的结构。比如常见的一行Dec 5 10:23:45 web01 sshd[12345]: Failed password for root from 203.0.113.7 port 22 ssh2拆开看就是时间Dec 5 10:23:45、主机名web01、进程名和PIDsshd[12345]、具体消息Failed password...。这种格式叫syslog格式理解它之后用grep按关键词搜用awk按位置取字段思路就打通了。Nginx的访问日志是另一套常见格式默认叫combined格式127.0.0.1 - - [10/Dec/2025:10:23:45 0800] GET /api/v1/user HTTP/1.1 200 512 http://example.com/ Mozilla/5.0 ...这里用空格和引号做了分隔IP是第一列请求时间在方括号里请求行是第六列状态码是第九列。知道这些字段位置写分析命令就有依据了。1.3 不同服务的日志差异每个服务都有自己的日志风格没有万能钥匙但有一套通用的勘察方法先看配置文件里log_path或logging相关参数确认日志写到哪再直接打开日志文件看头几十行了解格式。很多应用还支持日志等级配置比如Nginx的error_log可以指定debug、info、warn、error等级别调试时调到debug排查完再调回来否则生产环境会产生海量日志。注意别在业务高峰期随意改动日志等级尤其是数据库和高并发网关debug日志能把磁盘瞬间写满。我见过某团队把线上Nginx error_log调成debug半小时磁盘报警。2. 查看日志的基本姿势tail、head、less与grep组合2.1 实时跟踪日志tail -f 与 tail -F排查线上问题时最常用的是实时看日志。tail -f /var/log/messages可以持续输出新追加的内容。这里有个经典坑如果日志被logrotate轮转了即原来的文件被改名或者重建tail -f会一直盯着旧文件导致新日志不显示。正确做法是用大写的tail -F它会按文件名重新定位文件文件被重建后自动跟随新文件。日常操作我建议直接写tail -F能省很多不必要的事故。如果要同时看多个日志tail -F /var/log/nginx/access.log /var/log/nginx/error.log还能加-n 50先回放最近的50行再跟随。这个在调试接口时特别好用一边发请求一边看错误日志和访问日志。2.2 按行号与关键词定位less grep 的高效配合日志文件动不动几千行直接cat肯定不合适。less是最舒服的阅读工具支持上下翻页、按行号跳转、搜索。打开一个日志less /var/log/messages然后按ShiftG跳到末尾按g回到开头按/输入关键词回车就可以向下搜索按?向上搜索按n继续下一个匹配项。但很多时候我们不是漫无目的地看而是带着关键词来排查。比如我想找报错grep -i error /var/log/messages。-i忽略大小写避免漏掉ERROR、Error这些变体。但这样输出可能也很多更好的方式是先用grep error /var/log/messages | less把过滤后的内容交给less翻看。又或者配合-A、-B看上下文grep -B 2 -A 5 OutOfMemory /var/log/messages这样可以看到错误发生的背景和前因后果比单看一行有用得多。2.3 小心坑grep过滤后你可能会丢字段很多人用grep直接过滤然后发现拿到的内容不完整。比如Nginx日志里有一个请求体很大日志可能被截断或者换行显示grep单行匹配只能拿到断掉的部分。这时候可以考虑grep -P支持Perl正则或者干脆结合awk通过行内特征匹配。还有一点grep默认是“包含即匹配”有时候你想找以某个词开头的行就得多加几个条件。比如只看“Failed password”开头的行用grep ^Failed password反而会漏掉前面有时间戳的syslog格式。这种场景下匹配“Failed password”出现在任意位置就好不必执着于行首。还有一个进阶技巧如果日志文件很大比如超过500MB直接grep其实比较慢。可以先用split把文件按大小切块或者用less打开后再用less内部的搜索也能从末尾逐步加载。但最稳妥的办法还是下面要讲的sed按时间范围截取。3. 文本处理三剑客在日志分析中的实战3.1 sed按时间范围截取日志很多时候我们只关心某个时间段内的日志。比如今天上午10点到10点20分之间发生了什么grep不太好写因为时间字段在行首的格式可以用正则匹配但写起来容易错。用sed按行号或正则范围来截取就灵活得多。假设日志格式是Dec 5 10:23:45 ...我想截取10点整到10点20分的日志可以这样sed -n /Dec 5 10:00:00/,/Dec 5 10:20:59/p /var/log/messages但这里有个隐患如果10点20分59秒这一行恰好不存在范围会一直延伸到下一个匹配的10点20分59秒之前实际会导致多截取。更稳的做法是先grep找到起止行号再用sed -n 100,200p按行号截取。两个命令配合start$(grep -n Dec 5 10:00:00 /var/log/messages | head -1 | cut -d: -f1) end$(grep -n Dec 5 10:20:59 /var/log/messages | tail -1 | cut -d: -f1) sed -n ${start},${end}p /var/log/messages这样能精确截取到已有日志的范围。虽然写起来麻烦但避免了“范围穿透”的问题。3.2 awk按列提取和统计日志数据awk是日志分析的核心工具几乎每个做运维的都离不开它。awk默认以空白字符为分隔符适合syslog格式。比如我想列出所有尝试登录的来源IPawk /Failed password/ {print $(NF-3)} /var/log/secure为什么是NF-3上面那行Failed password for root from 203.0.113.7 port 22 ssh2用空格切开后from是倒数第4个字段IP是倒数第3个所以$(NF-3)正好取到。如果你不确定字段位置可以先awk {print NF, $0} | head打印每一行的字段总数和内容确认了再提取。对于Nginx日志字段分隔是空格但请求行里的引号含空格直接用awk {print $9}可以取状态码第9列。如果想取请求耗时那需要确认日志配置中是否加了$request_time通常它是最后一列。统计平均响应时间可以这样awk {sum $NF; count} END {if (count 0) printf avg %.3f\n, sum/count} /var/log/nginx/access.log$NF表示最后一个字段这一招可以统计任意数值列的平均值非常实用。3.3 综合实战统计某接口的响应时间和错误率这里我给大家一个可以直接改着用的完整示例。假设业务方反馈“最近接口变慢了”我们需要从访问日志里看/api/user/list这个接口的平均耗时和成功率。日志格式是combined最后一列是响应时间第9列是状态码第7列是请求行。我们可以一步步拆先确认字段tail -1 /var/log/nginx/access.log | awk {print IP:, $1, STATUS:, $9, REQ:, $7, TIME:, $NF}如果$7是整个/api/user/list HTTP/1.1这种带协议的内容可以用$7匹配开头来过滤awk $7 ~ /^\/api\/user\/list/ {print $NF} /var/log/nginx/access.log /tmp/time.txt然后把所有耗时求和、算平均、找最大值awk {sum$1; count; if($1max) max$1} END {printf count%d avg%.3f max%.3f\n, count, sum/count, max} /tmp/time.txt统计错误率也很简单找出状态码不等于200且不是3xx的请求占比awk $7 ~ /^\/api\/user\/list/ {total; if ($9 400) bad} END {printf total%d bad%d rate%.2f%%\n, total, bad, (total0 ? bad/total*100 : 0)} /var/log/nginx/access.log这段代码用到了awk里的三目运算符写法和C语言类似很实用。有了这两组数据就能回答“到底慢在哪”“错误率是不是升高了”而不是凭感觉猜。4. 日志轮转与清理别让磁盘被日志塞满4.1 logrotate的基本配置日志文件如果不清理几个月就能把磁盘写爆。系统自带的logrotate是标准答案。它的配置文件在/etc/logrotate.conf各个应用的独立配置在/etc/logrotate.d/下。我们拿Nginx举例它的配置大致是/var/log/nginx/*.log { daily missingok rotate 14 compress delaycompress notifempty create 0640 nginx adm sharedscripts postrotate [ -f /var/run/nginx.pid ] kill -USR1 cat /var/run/nginx.pid endscript }daily每天轮转一次。rotate 14保留最近14份日志。compress轮转后的旧日志用gzip压缩节省空间。delaycompress推迟一次压缩避免刚轮转的文件立即压缩导致某些工具写文件出问题。create轮转后新建同名日志文件并指定属主权限。postrotate在轮转后给Nginx发USR1信号让Nginx重新打开日志文件句柄。这一步非常关键否则Nginx还会继续往旧文件里写轮转就白做了。sharedscripts的意思是这些脚本只运行一次而不是每个日志文件都运行一次。配置好后可以用logrotate -d /etc/logrotate.conf做调试dry-run确认没问题再实际执行。4.2 手动轮转与压缩策略有时候日志文件已经很大了等不到系统轮转需要手动处理。比如messages已经1.2GB直接mv /var/log/messages /var/log/messages.bak再systemctl restart rsyslog但这期间可能丢失少量日志而且如果其他进程还持有文件句柄旧文件空间不会立即释放需要杀掉相关进程才释放。更稳妥的手动方式是用logrotate脚本logrotate -f /etc/logrotate.d/nginx-f强制执行不管是否到时间。手动处理时要注意轮转后旧日志是压缩状态需要用zcat或zgrep查看。命令记忆也很简单zcat对应catzgrep对应grepzless对应less。4.3 排查日志占满磁盘的紧急处理当df -h发现某个分区100%时第一反应不是删文件而是先找大文件du -ah /var/log | sort -rh | head -20然后看看有没有哪个日志已经巨大。有时候是某个写日志的进程把文件删了但没释放句柄用lsof | grep deleted可以查出来然后重启那个进程或evict句柄。还有一个小技巧不掉线地清空日志用truncate -s 0 /var/log/xxx.log这样文件大小归零而进程不用重启句柄依然有效。相比直接rmtruncate更安全能避免“空间没降下来”的怪问题。注意千万别在生产环境用rm -f /var/log/messages这种操作把文件删掉后rsyslog还在写原句柄你会看到ls没有文件但磁盘空间一直居高不下最后还得靠lsof找出来白白折腾。5. 常见问题与排查技巧实录5.1 日志文件被删除但空间不释放某次磁盘告警查看大文件时发现/var/log/messages不见了但df显示空间占用还是很高。原因就是rsyslog进程持有旧文件句柄。可以用这个命令查看lsof | grep deleted找到带deleted的进程和文件句柄后确认是对应服务然后通过重启服务释放。不需要重启整个系统。处理完后再用df -h验证。5.2 tail -f 与管道搭配的意外中断在脚本里用tail -f access.log | grep error想要实时过滤输出时你会发现当你用CtrlC中止后管道后的grep可能没有退出留下一个孤儿进程。这是因为管道两端的进程收到了不同的信号。解决方式在脚本里使用timeout或显式指定进程组。如果只是临时排查建议直接tail -F file | grep --line-buffered error加--line-buffered让grep逐行输出避免缓冲导致看不到实时内容。也可以不用管道改用less打开日志后按/error搜索这样既能看到上下文也不会产生多余进程。5.3 中文乱码与编码问题某些应用日志包含UTF-8中文用less查看时如果系统的locale不对会显示乱码。先检查环境变量echo $LANG通常需要LANGen_US.UTF-8或zh_CN.UTF-8。如果日志本身是GBK编码可以用iconv -f GBK -t UTF-8 日志文件转换后再看。但更奇怪的是有的日志文件名带中文在shell里显示成转义序列可以用ls -b看原始字节。别太依赖编辑器命令行工具配合好env设置基本能解决大多数乱码。5.4 按关键字统计的经典组合统计某个关键字出现次数新手喜欢grep -c但grep -c统计的是匹配行数。如果一行里出现多次也只会计一次。想要统计全部次数得这样grep -o error /var/log/messages | wc -l-o只输出匹配的部分每出现一次就输出一行然后wc -l数总和。统计多个关键词的分布可以写成循环for word in error warning timeout; do echo -n $word: grep -o $word /var/log/messages | wc -l done而如果想按IP统计访问次数经典的awk统计方式awk {count[$1]} END {for (ip in count) print count[ip], ip} /var/log/nginx/access.log | sort -rn | head -10这是awk数组用来做频率统计的典型场景count[$1]以IP为下标累加最后遍历打印。学会这个组合以后不管是统计访问来源还是统计报错模块都能举一反三。写在最后日志分析这块命令本身都不复杂真正的门槛是“组合思维”——什么时候该用grep过滤什么时候该用awk取列什么时候用sed截范围心里要有个谱。我个人习惯是先tail -F看实时状态再用grep less定位关键词最后用awk做统计量化。遇到跨时间段的排查优先想sed但务必用行号范围避免正则穿透。还有一个建议日常使用中养成随手alias几个高频组合的习惯比如把tail -F | grep error缩写成一个短命令能省不少重复输入。踩过几次坑之后你会慢慢发现日志不再是一堆杂乱文本而是一个有迹可循的现场拿着命令行就能层层拆开找到藏在表象下的真实原因。

相关新闻

重装系统后磁盘只剩C盘?分区丢失与数据恢复全指南

重装系统后磁盘只剩C盘?分区丢失与数据恢复全指南

我几乎每个月都能在各类电脑求助帖和身边人的聊天里看到这样一句话:“重装系统之后磁盘只剩一个C盘了,D盘E盘资料全没了,怎么办?”说实话,我第一次遇到这个问题时,第一反应也是心凉了半截。但干这行久了&am…

2026/10/16 3:41:07 阅读更多 →
Ubuntu安装RTX 50系列NVIDIA驱动:runfile实操与避坑指南

Ubuntu安装RTX 50系列NVIDIA驱动:runfile实操与避坑指南

1. 项目概述与方案选型RTX 50 系列发布之后,我身边因为装驱动翻车的案例已经攒了一堆。核心坑点其实很一致:新显卡和老驱动相互不认识,老仓库里又没有新包,最后折腾一晚上还在和黑屏搏斗。所以我打算把 Ubuntu 装 NVIDIA 50 系列驱…

2026/10/16 3:41:07 阅读更多 →
云领数智未来: 《云原生数据库产业发展与行业应用白皮书》重磅发布

云领数智未来: 《云原生数据库产业发展与行业应用白皮书》重磅发布

11月27日,移动云开发者大会在苏州举行。会上,移动云联合IDC重磅发布《云原生数据库产业发展与行业应用白皮书》(以下简称“白皮书”)。该白皮书全面解读了云原生数据库助力企业IT基础设施升级的路径,充分展示了移动云数…

2026/10/16 3:41:07 阅读更多 →

最新新闻

模板代码异常处理全攻略:从编译拦截到渲染降级

模板代码异常处理全攻略:从编译拦截到渲染降级

模板代码的异常处理,说难不难,说简单也不简单。我接过不少以模板渲染为核心的项目,从批量邮件通知、自动化报表到页面静态化,几乎每个项目在跑起来之后,第一波线上问题全出在模板这一层——变量名拼错、字段为空、循环…

2026/10/16 4:27:20 阅读更多 →
嵌入式MCU加密库实战:从算法选型到安全实现与避坑指南

嵌入式MCU加密库实战:从算法选型到安全实现与避坑指南

做嵌入式开发这些年,但凡接触过设备固件升级、数据透传、产线认证这类需求的,最后几乎都会撞上同一个问题:在资源受限的MCU上跑加解密,怎么跑才能兼顾速度、内存和安全性。我前面负责一个数据采集终端项目,要在主控芯片…

2026/10/16 4:27:20 阅读更多 →
TCP文件上传实战:从粘包半包到帧协议设计与Java实现

TCP文件上传实战:从粘包半包到帧协议设计与Java实现

我见过太多人初学网络编程时,写一个TCP聊天室或简单回显服务都很溜,但一碰到“文件上传”这种综合案例就卡壳。说白了,聊天室只需要考虑消息内容,而文件上传把网络通信里最麻烦的几个问题全集中在一起了——粘包、半包、大数据量传…

2026/10/16 4:27:20 阅读更多 →
every()和some()在对象数组中的正确用法与避坑指南

every()和some()在对象数组中的正确用法与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 4:27:20 阅读更多 →
STM32F103ZET6 CAN通信例程详解:从初始化到二次开发避坑指南

STM32F103ZET6 CAN通信例程详解:从初始化到二次开发避坑指南

简介:这份资源是面向嵌入式初学者与STM32开发者的CAN总线通信程序例程,基于STM32F103ZET6单片机与官方固件库编写,已在开发板上调试通过,可用于学习CAN外设初始化、报文收发与中断处理等核心环节,帮助读者快速搭建总线…

2026/10/16 4:27:20 阅读更多 →
Girvan-Newman算法实战:边介数计算与模块度优化详解

Girvan-Newman算法实战:边介数计算与模块度优化详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 4:26:19 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →