Shell 四剑客之一:grep 文本搜索实战

grep 是四剑客里最常用的:日志里捞错误、配置里找参数、代码里定位函数,第一反应就是 grep。它只干一件事——按模式找行,但把这件事做到极致。这篇讲 grep 的基本用法、正则速查和日志排障实战。

一、基本用法

# 在文件里找包含 error 的行
grep "error" /var/log/messages

# 常用选项
grep -i "error" app.log      # 忽略大小写
grep -v "DEBUG" app.log      # 反选:排除匹配的行
grep -n "error" app.log      # 显示行号
grep -c "error" app.log      # 只计数
grep -r "TODO" /eda/proj/    # 递归搜目录
grep --color=auto "error" app.log  # 高亮匹配部分

记住一个组合就够日常用:grep -rn "关键词" 目录,递归加行号,找代码、找配置、找日志都靠它。

二、正则速查

  • . 任意一个字符,* 前面那个出现 0 次或多次,^ 行首,$ 行尾。
  • [0-9] 一位数字,[a-z] 一位小写字母,[^0-9] 非数字。
  • \{2,4\} 出现 2 到 4 次,\(a\|b\) 二选一。写起来啰嗦就用 grep -E,扩展正则里直接写 {2,4} 和 (a|b)。
  • \bword\b 单词边界,搜 test 不会把 testing 也带出来。
# 扩展正则:找 IP 地址
grep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" access.log

# 找以 ERROR 开头或以 failed 结尾的行
grep -E "^(ERROR|FATAL)|failed$" app.log

# 只输出匹配的部分,不输出整行
grep -oE "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" access.log | sort | uniq -c | sort -nr | head

三、实战:日志排障

# 找报错,并看前后各 5 行上下文
grep -n -C 5 "FATAL ERROR" xeDebug.log

# 只看报错之后 3 行(比如看堆栈)
grep -n -A 3 "Segmentation fault" run.log

# 先看有多少种报错,再逐个查
grep -oE "(ERROR|FATAL|WARNING)[^:]*" sim.log | sort | uniq -c | sort -nr

-A、-B、-C 是排障神器:报错本身往往只有一行,原因在前后几行。先 -C 5 看上下文,再决定要不要扩大范围。

四、组合拳:grep + 管道

# 二次过滤:先找 error,再排除已知的无关报错
grep "error" app.log | grep -v "timeout"

# 找某个用户的报错
grep "user=admin" app.log | grep "error"

# 统计每个小时的报错数
grep "ERROR" app.log | cut -c1-13 | sort | uniq -c

五、性能与坑

  • 大文件:先 grep -c 看数量,再决定要不要全量输出;输出太多先重定向到文件慢慢看。
  • 二进制文件:grep 遇到二进制会说“匹配到二进制文件”,加 -a 当文本处理。
  • 排除目录:搜代码时排除 .git 和构建目录,grep -r --exclude-dir=.git --exclude-dir=build "TODO" .。
  • 别用 grep 查固定字符串还开正则:固定字符串用 grep -F,更快,还不用转义。

grep 的精髓就一句:先想清楚要找什么,再选最省事的写法。九成日常搜索,grep -rn 加 -A/-B/-C 就够了。

发表回复

后才能评论