grep
(Global Regular Expression Print)是 Linux/Unix 系统中最常用的文本搜索工具,通过正则表达式高效筛选匹配内容。它广泛用于日志分析、代码搜索、数据过滤等场景。以下是系统的 grep
学习指南:
一、基础语法
grep [选项] '搜索模式' [文件或目录]
-
搜索模式:支持普通字符串或正则表达式。
-
选项:控制匹配行为(如是否忽略大小写、递归搜索等)。
二、核心选项详解
1. 匹配控制
选项 | 作用 |
---|---|
-i | 忽略大小写(Case-insensitive),如 grep -i "error" 匹配 Error 、ERROR 等。 |
-v | 反向匹配(Invert match),显示不包含匹配项的行,如 grep -v "ignore" 。 |
-w | 全词匹配(Word match),如 grep -w "test" 不匹配 testing 。 |
-x | 整行匹配(Line match),如 grep -x "hello" 只匹配完全等于 hello 的行。 |
2. 输出控制
选项 | 作用 |
---|---|
-n | 显示匹配行的行号,如 grep -n "error" log.txt 输出 10:ERROR: file not found 。 |
-c | 统计匹配行数,如 grep -c "success" log.txt 输出匹配次数。 |
-o | 只输出匹配的部分(而非整行),如 grep -o "\d+" file.txt 只提取数字。 |
-A N | 显示匹配行及其后 N 行(After context),如 grep -A2 "error" log.txt 。 |
-B N | 显示匹配行及其前 N 行(Before context),如 grep -B1 "error" log.txt 。 |
-C N | 显示匹配行及其前后各 N 行(Context),等价于 -A N -B N 。 |
3. 文件与目录搜索
选项 | 作用 |
---|---|
-r | 递归搜索目录(Recursive),如 grep -r "password" /etc/ 。 |
-l | 只列出包含匹配项的文件名(不输出具体内容),如 grep -rl "TODO" src/ 。 |
-L | 只列出不包含匹配项的文件名,与 -l 相反。 |
-f | 从文件读取搜索模式,如 grep -f patterns.txt file.txt 。 |
三、正则表达式基础
grep
支持两种正则语法:
-
基本正则表达式(BRE):默认模式,部分元字符需转义(如
\.
,\*
,\+
)。 -
扩展正则表达式(ERE):通过
-E
选项启用,支持更强大的语法(如+
,?
,()
)。
常用元字符
元字符 | 含义 | 示例 |
---|---|---|
. | 匹配任意单个字符(除换行符) | grep "h.t" file.txt 匹配 hat , hot , hit 等。 |
* | 匹配前一个字符零次或多次 | grep "ab*c" file.txt 匹配 ac , abc , abbc 等。 |
[] | 匹配方括号内的任意字符 | grep "[aeiou]" file.txt 匹配包含元音的行。 |
[^] | 匹配不在方括号内的任意字符 | grep "[^0-9]" file.txt 匹配不包含数字的行。 |
^ | 匹配行首 | grep "^error" file.txt 匹配以 error 开头的行。 |
$ | 匹配行尾 | grep "end$" file.txt 匹配以 end 结尾的行。 |
| | 或逻辑(需 -E 选项) | grep -E "cat|dog" file.txt 匹配包含 cat 或 dog 的行。 |
() | 分组(需 -E 选项) | grep -E "(ab)+" file.txt 匹配包含一个或多个 ab 的行。 |
+ | 匹配前一个字符至少一次(需 -E 选项) | grep -E "a+" file.txt 匹配包含至少一个 a 的行。 |
? | 匹配前一个字符零次或一次(需 -E 选项) | grep -E "colou?r" file.txt 匹配 color 或 colour 。 |
四、实战案例
1. 日志分析
- 查找包含 "ERROR" 的行,并显示前后3行:
grep -C3 "ERROR" app.log
- 统计今天的访问日志数量:
grep "$(date +%Y-%m-%d)" access.log | wc -l
2. 代码搜索
- 在项目中查找所有 TODO 注释:
grep -r "TODO" src/
- 查找未使用的函数定义(Python):
grep -r "^def [a-zA-Z_]" src/ | grep -v -f <(grep -r "[a-zA-Z_]\." src/)
3. 数据过滤
- 提取 IP 地址:
grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" access.log
- 过滤包含敏感词的行:
grep -v -E "password|credit_card" data.txt
4. 多条件搜索
- 同时匹配 "error" 和 "connection":
grep "error" log.txt | grep "connection"
- 匹配 "error" 但排除 "warning":
grep "error" log.txt | grep -v "warning"
五、与其他工具组合
- 与
sed
/awk
结合处理文本:
# 提取匹配行的第2和第3个字段
grep "pattern" file.txt | awk '{print $2, $3}'
# 替换匹配内容
grep "old" file.txt | sed 's/old/new/g'
- 与
find
结合搜索文件:
# 在 .txt 文件中搜索 "hello"
find . -name "*.txt" -exec grep "hello" {} \;
# 更高效的写法(使用 xargs)
find . -name "*.txt" | xargs grep "hello"
- 统计词频:
grep -o "\w\+" text.txt | sort | uniq -c | sort -nr
六、性能优化与注意事项
- 大文件搜索:
- 使用 grep -m1
找到第一个匹配项后立即退出。
- 使用 zgrep
直接搜索压缩文件(如 .gz
)。
- 正则表达式陷阱:
- 复杂正则优先使用 -E
选项,避免过多转义。
- 使用 \b
匹配单词边界,如 grep -E "\bcat\b" file.txt
只匹配独立的 cat
。
- 编码问题:
- 使用 LC_ALL=C grep
以字节方式匹配,避免字符编码干扰。
七、学习资源推荐
- 官方文档:
- 在线工具:
- Regex101:可视化调试正则表达式。
- RegExr:带交互式解释的正则测试器。
- 练习网站:
- Regex Crossword:通过游戏学习正则表达式。
掌握 grep
后,你可以快速定位和筛选文本数据,大幅提升工作效率。多结合实际场景练习,逐渐掌握正则表达式的精髓!