grep(Global Regular Expression Print) 是 Linux/Unix 系统中最强大的文本搜索工具。它的核心功能是在一个或多个文件中搜索包含指定模式(字符串或正则表达式)的行,并将匹配的行打印出来。
它是系统管理员、开发者和数据分析师的“瑞士军刀”,常与find、xargs、awk等命令组合使用。
1. 基本语法
grep [选项] "搜索模式" [文件...]- 搜索模式:可以是普通字符串,也可以是正则表达式。
- 文件:可以是一个文件、多个文件、通配符(
*.log),或者省略(默认从标准输入读取,常用于管道)。
2. 核心常用选项
| 选项 | 含义 | 示例 |
|---|---|---|
| -i | 忽略大小写(Ignore case) | grep -i "error" log.txt(匹配 Error, ERROR, error) |
| -v | 反向选择(Invert match),显示不匹配的行 | grep -v "debug" log.txt(排除含 debug 的行) |
| -n | 显示行号(Line number) | grep -n "fail" script.sh |
| -c | 统计数量(Count),只输出匹配行数 | grep -c "404" access.log |
| -l | 只显示文件名(Files with matches),不显示内容 | grep -l "TODO" *.py |
| -L | 显示未包含匹配模式的文件名 | grep -L "copyright" *.md |
| -r/-R | 递归搜索(Recursive),遍历目录及其子目录 | grep -r "password" /etc/ |
| -w | 全字匹配(Word),只匹配完整的单词 | grep -w "root" /etc/passwd(不匹配 proot) |
| -A n | 显示匹配行及其后n 行 (After) | grep -A 3 "Exception" app.log |
| -B n | 显示匹配行及其前n 行 (Before) | grep -B 2 "Error" app.log |
| -C n | 显示匹配行及其前后各 n 行 (Context) | grep -C 5 "Crash" system.log |
| -E | 使用扩展正则表达式(Equivalent toegrep) | `grep -E "err |
| -F | 固定字符串匹配 (Fixed string),关闭正则特性,速度最快 | grep -F "*.txt" file(查找字面量 *.txt) |
| -o | 只输出匹配的部分,而不是整行 | grep -o "[0-9]\+" log.txt(只提取数字) |
| --color | 高亮显示匹配部分 (通常默认开启) | grep --color=auto "key" file |
3. 正则表达式基础 (Regular Expressions)
grep支持两种正则语法:
- 基础正则 (BRE):默认模式。特殊字符需转义(如
\+,\?,\|)。 - 扩展正则 (ERE):使用
-E选项。特殊字符无需转义,语法更直观(推荐)。
常用元字符 (配合-E使用)
| 符号 | 含义 | 示例 (grep -E) | 匹配结果 |
|---|---|---|---|
. | 匹配任意单个字符 | gr.p | grip, group, gr8p |
* | 匹配前一个字符 0 次或多次 | ab*c | ac, abc, abbc |
+ | 匹配前一个字符 1 次或多次 | ab+c | abc, abbc (不匹配 ac) |
? | 匹配前一个字符 0 次或 1 次 | colou?r | color, colour |
^ | 匹配行首 | ^Error | 以 Error 开头的行 |
$ | 匹配行尾 | end$ | 以 end 结尾的行 |
[] | 匹配括号内任意一个字符 | [0-9]或[aeiou] | 任意数字 或 任意元音 |
[^] | 匹配非括号内的字符 | [^0-9] | 非数字字符 |
| ` | ` | 或(逻辑 OR) | `error |
() | 分组 | (abc)+ | abc, abcabc |
示例:
# 查找以 "ERROR" 开头且以数字结尾的行 grep -E "^ERROR.*[0-9]$" app.log # 查找包含 IP 地址格式的行 (简单版) grep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" access.log4. 实战场景组合拳
🔹 场景 1:在多个文件中递归搜索代码
查找当前目录下所有.py文件中包含import os的行,并显示文件名和行号。
grep -rn "import os" --include="*.py" .
-r: 递归;-n: 行号;--include: 限定文件类型。
🔹 场景 2:查看日志上下文
当程序报错时,不仅要看报错行,还要看报错前 5 行和后 5 行的上下文,以便定位原因。
grep -C 5 "Segmentation fault" application.log🔹 场景 3:统计特定状态码的数量
统计 Nginx/Apache 日志中 404 错误的数量。
grep -c " 404 " access.log🔹 场景 4:提取特定字段 (配合-o)
从日志中提取所有的邮箱地址。
grep -oE "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" mail_log.txt🔹 场景 5:管道组合 (Pipe)
结合ps和grep查找进程(注意避免 grep 到自身):
# 方法 A: 使用 -v 排除 grep 进程 ps aux | grep "nginx" | grep -v "grep" # 方法 B: 技巧性写法 (匹配 n[g]inx) ps aux | grep "[n]ginx"🔹 场景 6:与 find 和 xargs 联动
在所有.conf配置文件中查找包含 "ssl" 的行:
find /etc -name "*.conf" -type f -exec grep -l "ssl" {} \; # 或者 find /etc -name "*.conf" -type f | xargs grep -l "ssl"5. 性能优化与注意事项
固定字符串加速 (
-F):
如果你只是搜索普通字符串(不含正则符号),加上-F选项速度会快很多,因为它关闭了正则引擎# 快速搜索大量日志中的固定错误码 grep -F "Connection reset by peer" huge_log.txt二进制文件警告:
如果在二进制文件(如可执行程序)中搜索,grep可能会输出Binary file ... matches。- 使用
-a(text) 强制将二进制当作文本处理:bashgrep -a "secret_key" binary_file
- 使用
大文件搜索:
对于巨大的日志文件,grep依然非常高效,但配合--line-buffered可以在管道实时处理时减少延迟。颜色配置:
如果grep没有自动高亮,可以在~/.bashrc中添加别名alias grep='grep --color=auto'
总结
- 简单查找:
grep "keyword" file - 忽略大小写/显示行号:
grep -in "keyword" file - 递归查找代码:
grep -rn "pattern" . - 复杂模式:
grep -E "pattern1|pattern2" - 只看匹配内容:
grep -o "pattern" - 纯文本极速搜:
grep -F "string"
掌握grep是熟练使用 Linux 命令行进行文本处理和故障排查的基石