1. 为什么选择 ripgrep (rg)?
rg 是目前最快的命令行搜索工具,它比 grep 更快,且默认具备“聪明”的特性:
- 自动递归:默认搜索当前目录及所有子目录。
- 尊重忽略规则:默认不搜索
.gitignore、隐藏文件和二进制文件。 - 智能输出:自动高亮匹配行,并显示行号。
2. 核心搜索技巧(正则与匹配控制)
如果你熟悉正则,rg 默认的正则引擎(Rust Regex)与 PCRE 高度相似。
| 功能 | 命令示例 | 说明 |
|---|---|---|
| 正则匹配 | rg "\d{3}-\d{4}" | 默认即支持正则。 |
| 字面量匹配 | rg -F "fn main()" | -F 关闭正则,将字符视为普通文本。 |
| 智能大小写 | rg -S "Pattern" | 推荐! 小写全搜,含大写则精确匹配。 |
| 多行搜索 | rg -U "start\n.*end" | -U 允许跨行匹配。 |
| 仅匹配单词 | rg -w "test" | 相当于正则的 \btest\b。 |
3. 文件过滤秘籍(解决“搜不到”的头号原因)
当你发现明明文件在那儿,但 rg 搜不出来时,通常是由于 过滤规则 或 编码 引起的。
3.1 突破忽略规则 (The u Flags)
rg 默认很保守,使用 -u 来提升搜索权限:
rg -u:搜被.gitignore忽略的文件。rg -uu:搜索 gitignore + 隐藏文件 (如.env)。rg -uuu:搜索所有,包括二进制文件。
3.2 Glob 语法辅助 (-g)
-g 用于指定或排除特定路径。注意:在 Shell 中始终为路径加上引号。
- 递归包含:
rg "key" -g "**/test/*.c"(搜所有 test 目录下的 .c 文件) - 排除特定文件:
rg "key" -g "!*.log"(排除所有日志文件) - 组合拳:
rg "key" -g "*.{c,h}"(只搜 C 语言头文件和源文件)
3.3 编码问题(中文搜索必看)
rg 默认只识别 UTF-8。如果文件是 GBK(Windows 常见编码):
- 指定编码:
rg -E gbk "中文关键字"
4. Glob 模式快速参考表
-g 参数支持的规则与 .gitignore 一致:
| 语法 | 描述 | 示例 |
|---|---|---|
* | 匹配任意字符(不跨目录) | *.js |
** | 匹配任意层级目录 | **/README.md |
? | 匹配单个字符 | file?.txt |
{} | 匹配集合中的任意项 | *.{c,h} |
[] | 匹配字符范围 | [0-9].log |
! | 排除模式 | !vendor/** |
/ | 锚定当前目录(不递归) | /main.c (仅限根目录) |
5. 结果展示与上下文(代码排查神器)
当你需要查看代码前后的逻辑时:
- 显示上下文:
rg -A 3(After): 匹配行后 3 行。rg -B 3(Before): 匹配行前 3 行。rg -C 3(Context): 前后各 3 行。
- 只打印文件名:
rg -l "pattern"(常用于配合管道符:rg -l "deprecated" | xargs rm) - 正则替换(不修改文件):
rg "(\w+): (\d+)" -r "$1 => $2"(终端输出时改变显示格式)
6. 场景化 Cheat Sheet
场景 A:在复杂的 C 项目中找特定的中文注释
# 忽略 gitignore,考虑 GBK 编码,且只在名为 singleBoardTest.c 的文件中搜
rg -u -E gbk "以太网测试" -g "**/singleBoardTest.c"场景 B:搜索除了 node_modules 之外的所有 JS 文件中的某个 API
# 虽然 rg 默认就跳过 node_modules,但这是一个显式排除的例子
rg "fetchData" -g "*.js" -g "!node_modules/**"场景 C:查找所有的 TODO 并展示文件名和行号
rg -n "TODO:" 场景 D:统计匹配到的行数
rg -c "Error" 7. 进阶小技巧:配置文件
如果你不想每次都输入 --smart-case,可以在本地创建配置文件。
- 创建文件
~/.ripgreprc。 - 添加内容:
--smart-case --max-columns=200 --type-add web:*.{html,css,js}* - 在
.bashrc或.zshrc中添加环境变量:export RIPGREP_CONFIG_PATH=$HOME/.ripgreprc
总结:
rg搜索不到东西时,依次检查:路径通配符 (-g "**/...") → 忽略文件 (-u) → 文件编码 (-E gbk)。