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,可以在本地创建配置文件。

  1. 创建文件 ~/.ripgreprc
  2. 添加内容:
    --smart-case
    --max-columns=200
    --type-add
    web:*.{html,css,js}*
  3. .bashrc.zshrc 中添加环境变量: export RIPGREP_CONFIG_PATH=$HOME/.ripgreprc

总结rg 搜索不到东西时,依次检查:路径通配符 (-g "**/...") 忽略文件 (-u) 文件编码 (-E gbk)