路线图

文本查看与搜索

星辉 2026-07-02 阅读 6 min 1,117 字 路线图
文本查看与搜索 封面

Linux 运维基础 · 第六章 目标:掌握从海量日志中快速定位目标信息的能力


1. 概述#

运维的日常就是:日志、日志、日志。服务挂了 — 看日志;性能慢了 — 看日志;用户说登录不了 — 看日志。本章覆盖从"打开文件看一眼"到"在几 GB 的日志里秒定位问题行"的全部技能。

核心工具链:cat/less/head/tail 负责查看,grep 负责搜索,正则表达式负责精确匹配。


2. 查看文件内容#

2.1 cat — 全量输出#

bash
cat file.txt                    # 全量输出到终端
cat -n file.txt                 # 带行号输出
cat file1.txt file2.txt > merged.txt  # 合并多个文件

注意:不要在几百 MB 的日志上用 cat——它会一次性全量输出,终端卡死是小事,远程 SSH 带宽被打满才麻烦。大文件用 less

2.2 less — 分页浏览(运维首选)#

bash
less /var/log/syslog             # 打开文件,分页浏览

# less 内的快捷键(和 man/more 共用)
# Space / b       向下翻页 / 向上翻页
# g / G           跳到文件开头 / 文件末尾
# /keyword        向下搜索
# ?keyword        向上搜索
# n / N           下一个匹配 / 上一个匹配
# q               退出
# -N 启动参数     显示行号
# -i 启动参数     搜索忽略大小写

less -N /var/log/syslog          # 显示行号
less +F /var/log/syslog          # 类似 tail -f,实时跟踪
# 在 less 中按 Ctrl+C 停止跟踪,按 F 恢复跟踪

2.3 head / tail — 看头看尾#

bash
# head:看文件开头
head -n 20 /var/log/syslog       # 前 20 行
head /var/log/syslog             # 不带 -n 时默认前 10 行

# tail:看文件末尾
tail -n 50 /var/log/syslog        # 最后 50 行
tail -n +100 file.txt             # 从第 100 行开始到末尾

# tail -f:实时跟踪(最重要)
tail -f /var/log/syslog           # 实时看日志增长
tail -f /var/log/syslog /var/log/auth.log  # 同时跟踪多个文件
tail -n 100 -f /var/log/syslog    # 先显示最后 100 行,再实时跟踪

3. grep:文本搜索的核心#

grep 是运维的"搜索工具"。日志排查、配置审计、进程过滤——到处都用。

3.1 基本用法#

bash
grep "error" /var/log/syslog             # 在文件中搜索
grep "error" *.log                       # 搜索多个文件
grep "error" /var/log/*                  # 通配符

3.2 核心参数#

参数含义使用场景
-i忽略大小写grep -i "error" 能匹配 Error/ERROR/error
-r递归搜索目录grep -r "502" /var/log/nginx/
-n显示行号grep -n "timeout" app.log 直接定位到第几行
-v反向匹配(不包含)grep -v "DEBUG" app.log 过滤掉 DEBUG 行
-c统计匹配行数grep -c "ERROR" app.log 有多少行包含 ERROR
-E扩展正则表达式grep -E "error|timeout|failed" 或的关系
-w精确匹配整个单词grep -w "err" 不匹配 "error",只匹配独立的 "err"
-A N显示匹配行及后面 N 行grep -A 5 "Exception" 看异常的调用栈
-B N显示匹配行及前面 N 行grep -B 2 "ERROR" 看错误前发生了什么
-C N显示匹配行及前后 N 行grep -C 3 "timeout" 看完整的上下文
-l只显示文件名grep -rl "TODO" src/ 列出所有包含 TODO 的文件
-o只输出匹配的部分(不输出整行)grep -oE '[0-9.]+' access.log 只把 IP 抠出来,配合 sort/uniq 统计
-F固定字符串匹配(不解析正则)grep -F '1.2.3.4' f:点号当字面量,快且不怕特殊字符
-PPerl 兼容正则(PCRE)grep -P '\d{3}' 支持 \d \w \s、断言、非贪婪 *?
--color高亮匹配关键词多数系统默认开启(--color=auto

3.3 常用组合#

bash
# 递归搜索:在所有 Nginx 日志中找 502 错误
grep -rn "502 Bad Gateway" /var/log/nginx/    # r=递归, n=行号

# 上下文:看 ERROR 前 3 行 + 后 5 行
grep -B3 -A5 "ERROR" app.log

# 排除干扰:找 ERROR 但排除已知的无关错误
grep "ERROR" app.log | grep -v "known_ignore_pattern"

# 统计:看每种错误出现了多少次
grep "ERROR" app.log | awk '{print $NF}' | sort | uniq -c | sort -rn

# 多条件或:找 error 或 timeout 或 failed
grep -E "error|timeout|failed" app.log
grep -e "error" -e "timeout" -e "failed" app.log  # 等价写法

# 排除注释和空行:只看有效配置
grep -v "^#" /etc/nginx/nginx.conf | grep -v "^$"
# "^#" 行首是 # 的注释行,"^$" 是空行

4. 正则表达式入门#

配合 grepsedawk 使用正则,威力翻倍。

4.1 三种流派:BRE / ERE / PCRE(最大的坑)#

正则不是"一种"语法,Linux 下有三套,grep 用不同参数切换:

流派grep 参数说明
BRE(基础正则)grep(默认)+ ? { } | ( )普通字符,要当元字符必须转义成 \+ \? \{ \} \| \( \)
ERE(扩展正则)grep -E+ ? { } | ( ) 直接就是元字符,不用转义(想匹配字面量才转义)
PCRE(Perl 正则)grep -PERE 基础上再加 \d \w \s(?=...) 断言、*? 非贪婪等

易错点:同一个意图,BRE 和 ERE 的写法正好相反。

bash
# 匹配 "abc 或 abbc"(b 出现 1 次以上)
grep    'ab\+c' f      # BRE:+ 要转义
grep -E 'ab+c'  f      # ERE:+ 直接用

# 分组 + 或
grep    '\(err\|warn\)' f    # BRE:() 和 | 都要转义
grep -E '(err|warn)'    f    # ERE:干净利落

# 记忆:ERE 里“加了反斜杠反而变回字面量”。写正则优先用 grep -E,省心。

. * [ ] ^ $ 在 BRE / ERE 里行为一致,不用管流派;出问题的永远是 + ? { } | ( )。 PCRE(-P)依赖 libpcre,极简系统(BusyBox)可能没有;这时退回 -E

4.2 基础元字符#

下表按 ERE(grep -E 语法列出。若用默认 BRE,+ ? { } | ( ) 这几行需按上表加反斜杠。

元字符含义示例(ERE)
.匹配任意单个字符h.t 匹配 hat/hit/hot
*前一个字符出现 0 次或多次ab*c 匹配 ac/abc/abbc
+前一个字符出现 1 次或多次ab+c 匹配 abc/abbc(BRE 写 ab\+c
?前一个字符出现 0 次或 1 次ab?c 匹配 ac/abc(BRE 写 ab\?c
[]字符类,匹配方括号内任意字符[Hh]ello 匹配 Hello/hello
[^]否定字符类[^0-9] 非数字的字符
^行首^ERROR 行首的 ERROR
$行尾done$ 行尾的 done
|error|timeout(BRE 写 error\|timeout
()分组(error|timeout)(BRE 写 \(error\|timeout\)
\转义\. 匹配字面的点
{n,m}前一个字符出现 n 到 m 次[0-9]{2,4} 匹配 2-4 位数字(BRE 写 \{2,4\}

4.3 运维常用正则示例#

bash
# 匹配 IP 地址(简化版)
grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' access.log

# 匹配时间戳格式 [01/Jul/2025:10:30:15]
grep -E '\[[0-9]{2}/[A-Z][a-z]{2}/[0-9]{4}:[0-9]{2}:[0-9]{2}:[0-9]{2}' access.log

# 匹配 HTTP 状态码(三位数)
grep -E ' [0-9]{3} ' access.log

# 匹配以 ERROR 或 FATAL 开头的行
grep -E '^(ERROR|FATAL)' app.log

# 匹配行尾是分号或逗号
grep -E '[,;]$' data.txt

# 匹配包含数字 >= 500 的行(简化)
grep -E '5[0-9]{2}' access.log

5. 实战场景#

实战 1:实时监控错误日志#

bash
# 场景:服务刚上线,需要实时看有没有错误

# 方法 1:tail -f + grep
tail -f /var/log/myapp/app.log | grep -i "error"

# 方法 2:同时高亮多个关键词
tail -f /var/log/myapp/app.log | grep -E --color "error|timeout|exception|fatal"

# 方法 3:看错误的同时排除噪音
tail -f /var/log/myapp/app.log | grep -i "error" | grep -v "DEBUG\|known_bug"

实战 2:排查 Nginx 502 错误#

bash
# Step 1:确认 502 的范围和时间分布
grep -rn "502" /var/log/nginx/ | wc -l
# 一共多少条 502

# Step 2:看最近 10 条 502
grep "502" /var/log/nginx/access.log | tail -10

# Step 3:502 对应的 upstream 是哪台
grep "502" /var/log/nginx/error.log | tail -10
# 看到 upstream: "http://10.0.1.5:8080/..."

# Step 4:统计哪些 URI 出 502 最多
grep " 502 " /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head
# 找到最频繁出 502 的接口路径

# Step 5:统计出 502 最多的客户端 IP(grep -o 组合拳)
grep " 502 " /var/log/nginx/access.log \
  | grep -oE '^[0-9]{1,3}(\.[0-9]{1,3}){3}' \
  | sort | uniq -c | sort -rn | head
#   grep -oE 只抠出行首 IP → sort 排序 → uniq -c 计数 → sort -rn 倒序 → head 取 TopN
#   这套“grep|sort|uniq -c|sort -rn|head”是日志分析的万能组合拳

实战 3:找 K8s Pod 日志中的错误#

bash
# 看 Pod 最近 200 行日志中的 ERROR
kubectl logs pod-name --tail=200 | grep ERROR

# 看 Pod 日志,实时过滤错误
kubectl logs -f pod-name | grep -E "ERROR|FATAL|Exception"

# 看多个 Pod(标签筛选)的日志
kubectl logs -l app=myapp --tail=100 | grep -i error

6. 性能提示#

bash
# 大文件搜索:不要 cat 全量再 pipe grep(极慢)
cat 10GB.log | grep "error"         # 错误!cat 读全部再传给 grep

# 正确方式:让 grep 直接读文件
grep "error" 10GB.log               # grep 内部做了优化

# 递归搜索大目录时加限制
grep -rn "error" /var/log/          # 小心遍历所有子目录
grep -rn "error" /var/log/nginx/    # 限制范围

# 如果知道文件后缀,加 --include
grep -rn "error" /var/log/ --include="*.log"

7. 查看工具速查表#

命令用法适用场景
catcat file.txt几十行的小文件
cat -ncat -n file.txt小文件+需要行号
lessless huge.log大文件、分页浏览
less +Fless +F file.log打开后自动实时跟踪
head -nhead -n 20 file只看开头几行
tail -ntail -n 50 file只看末尾几行
tail -ftail -f app.log实时跟踪日志增长

其他实用查看命令#

bash
# wc:统计行数、单词数、字节数
wc -l access.log              # 日志有多少行
wc -c file.txt                # 文件多少字节
find . -name "*.go" -exec cat {} + | wc -l  # 项目总代码行数

# file:判断文件类型
file unknown_file             # 不确定是什么文件时用这个
file /bin/ls                  # ELF 64-bit executable

# stat:查看文件的详细元数据
stat /etc/passwd
# 看 inode、权限、三个时间戳(atime/mtime/ctime)

8. 小结#

知识点一句话记忆
查看小文件 cat -n,大文件 less,实时 tail -f
grep 核心-rn 递归+行号,-v 排除,-o 只出匹配串,-A/-B/-C 上下文
正则流派默认 BRE(+?{}|() 要转义),-E 用 ERE(不转义),-P 用 PCRE
正则元字符. 任意字符,* 0-N 次,[] 字符类,^ 行首,$ 行尾
不要 cat 大文件grep 直接读文件更快

上一章:五、用户与组管理 下一章:七、文本变换与提取