做什么
在文件或输入流里按正则匹配查找行。命令行核心工具之一。
常用参数
| 参数 | 含义 |
|---|---|
-i |
忽略大小写 |
-n |
显示行号 |
-v |
反向(不匹配的行) |
-r / -R |
递归找目录 |
-l |
只显示文件名 |
-c |
只数匹配行数 |
-A N |
匹配行 + 后 N 行 |
-B N |
匹配行 + 前 N 行 |
-C N |
匹配行 + 前后各 N 行 |
-E |
扩展正则(启用 ` |
-F |
字面匹配(不当正则) |
-o |
只输出匹配的部分 |
-w |
整词匹配 |
--color=auto |
高亮匹配 |
--include="*.py" |
递归时只看某后缀 |
--exclude-dir=node_modules |
递归时排除目录 |
实战
grep ERROR app.log
grep -i error app.log # 忽略大小写
grep -n ERROR app.log # 加行号
grep -v DEBUG app.log # 排除 DEBUG 行
grep -c ERROR app.log # 数有多少行
# 递归搜代码
grep -rn "TODO" src/
grep -rn --include="*.py" "import os" .
# 多模式
grep -E "(error|warning)" app.log
grep "error\|warning" app.log
# 整词
grep -w "log" file.txt # 不匹配 "logger" 等
# 上下文
grep -A 3 ERROR app.log # 后 3 行
grep -B 2 ERROR app.log # 前 2 行
grep -C 2 ERROR app.log # 前后各 2 行
正则速查
. 任意一个字符
* 前面字符 0+ 次
+ 前面字符 1+ 次(需 -E 或 \+)
? 前面字符 0/1 次(需 -E 或 \?)
^ 行首
$ 行尾
[abc] 字符集中之一
[^abc] 字符集外的
[0-9] 数字
\d 数字(需 -P)
\b 词边界
| 或(需 -E 或 \|)
实战 2:分析 Nginx 日志
# 找 5xx
grep " 5[0-9][0-9] " access.log
# IP 频次
grep -oE '^[0-9.]+' access.log | sort | uniq -c | sort -rn | head
# 看 ERROR 上下文
grep -C 5 "Connection refused" app.log
现代替代:ripgrep(rg)
sudo apt install ripgrep
rg "TODO" src/
rg 是 Rust 写的——比 grep 快 5-10 倍,默认递归 + 默认尊重 .gitignore。日常代码搜索强烈推荐。
坑
- 默认 grep 是 POSIX 基本正则——
+?|需要\+\?\|或用-E grep -r在某些 GNU 版本默认不跟软链接——加-rvs-R(不同 GNU 版本略有差异)- 大文件 grep 慢——加
LC_ALL=C grep(关掉 unicode 处理)能快几倍