ripgrep(命令行叫 rg)是当下最受欢迎的代码搜索工具,它能以远超 grep 的速度在海量源码中定位关键字符串。相比传统 grep,ripgrep 默认就遵守 .gitignore、自动跳过隐藏目录、并行遍历文件,几乎无需额外配置就能直接上手。本文从安装到工程化实战,带你用 rg 把日常代码搜索提速十倍。
一、为什么需要 ripgrep
grep 是 Unix 世界的老牌搜索命令,但在现代前端/后端单体仓库里越来越吃力:它能搜到 node_modules、.git、构建产物,结果被噪声淹没;不支持按文件类型过滤;递归大目录时单线程串行扫盘,速度慢。ripgrep 正是为「在代码仓库里找东西」这个场景而生,默认行为就贴合开发者习惯。
以一个典型前端 monorepo 为例,node_modules 往往有数十万文件、几个 GB,grep 会把绝大部分时间浪费在扫描这些第三方依赖上;ripgrep 一行配置都不用写就直接跳过,搜索时间从几十秒降到几百毫秒。更重要的是,它的输出默认带文件路径、行号和匹配高亮,团队协作时把结果贴给别人也能一眼定位。对个人开发者,这种「即装即用」的体验意味着你不再需要为了一次临时搜索去拼一长串 grep -r –include 参数。
二、安装 ripgrep
ripgrep 是 Rust 编写的单一二进制,几乎每个包管理器都有。任选其一即可:
# macOS / Linux (Homebrew)
brew install ripgrep
# Debian / Ubuntu
sudo apt install ripgrep
# Fedora / RHEL
sudo dnf install ripgrep
# Windows (Scoop)
scoop install ripgrep
# 或用 Rust 工具链
cargo install ripgrep
# 验证
rg --version
三、基础搜索:从 grep 无缝迁移
rg 的搜索语法与 grep 高度兼容,但默认就递归、默认就彩色高亮、默认就带行号。最常用的一组命令:
# 在当前目录递归搜索 TODO
rg TODO
# 忽略大小写
rg -i error
# 显示行号(默认已显示)并统计匹配数
rg -n --stats "TODO"
# 只列出包含匹配的文件名
rg -l "FIXME"
# 只输出匹配到的那一段文本(而非整行)
rg -o "\d{4}-\d{2}-\d{2}"
四、ripgrep 与其他搜索工具对比
| 工具 | 默认遵守 .gitignore | 按类型过滤 | 并行 | 典型场景 |
|---|---|---|---|---|
| grep | 否 | 需 xargs | 否 | 通用文本 |
| ack | 是 | 弱 | 否 | 代码搜索 |
| ag (The Silver Searcher) | 是 | 是 | 部分 | 代码搜索 |
| ripgrep (rg) | 是 | 强 (-t) | 是 | 现代代码仓库 |
结论很直接:ripgrep 在「遵守忽略规则 + 类型过滤 + 并行速度」三项上全面领先,且命令更短。这也是 GitHub 官方代码搜索、VS Code 内置搜索背后都在用类似引擎的原因。如果你习惯了 ack 或 ag,迁移成本几乎为零,因为常用参数(如 -i、-w、-C)完全保持一致。
五、高频参数实战
下面这组参数覆盖了 90% 的日常需求,建议直接记到肌肉记忆里。把它们组合使用,几乎能表达任何搜索意图:
# 只在 Python 文件里搜
rg -t py "def main"
# 排除测试目录,只看 src
rg "TODO" -g '!tests/' -g '!*.test.js'
# 显示匹配行上下各 3 行上下文
rg -C 3 "panic"
# 只匹配完整单词
rg -w "log"
# 以 JSON 输出,便于脚本二次处理
rg --json "error"
# 当作纯字符串搜索(正则元字符原样匹配)
rg -F "a.b($x)"
# 统计每种文件类型命中数
rg --stats -t js "TODO"
小技巧:-t 支持的组合很多,rg --type-list 会列出全部内置类型(py、js、go、md……),也可以自己定义类型,比如把 .tf 文件归到 terraform 下,再 rg -t terraform 搜索。
六、忽略规则与 .ripgreprc 配置
ripgrep 的忽略逻辑是:先读 .gitignore,再读 .ignore 和 .rgignore,最后读全局配置。把常用参数写进 ~/.config/ripgrep/rc 后,每次输入 rg 都自动带上:
# ~/.config/ripgrep/rc
--hidden
--glob=!.git/
--smart-case
--line-number
--colors=match:fg:green
--colors=path:fg:cyan
忽略规则的优先级是:.rgignore 高于 .ignore 高于 .gitignore,越靠近项目的文件权重越高;团队可以把通用规则写进仓库根的 .rgignore 并提交,保证所有人搜索口径一致。想临时覆盖某条忽略规则,用 --no-ignore 强制全量扫描,或用 -u 逐级放宽忽略(-uu 连隐藏文件一起搜)。排查「明明有却搜不到」的问题时这个开关极好用。
七、与 fzf 联动做交互式搜索
ripgrep 负责「找」,fzf 模糊查找 负责「选」。两者组合可以做出一个飞快的「全局模糊跳转」工作流:
# 用 rg 生成文件名列表,交给 fzf 交互式筛选
rg --files | fzf --preview 'bat --color=always {}'
# 搜内容并跳转到命中行(配合 vim 打开)
rg --line-number --no-heading "" | fzf | awk -F: '{print $1}' | xargs -o vim
这条组合拳的价值在于:rg 负责「精准 + 快」,fzf 负责「模糊 + 交互」。当你只记得大概关键词、不确定在哪个文件时,先 rg 缩小范围再用 fzf 肉眼挑,比反复试正则高效得多。
八、在编辑器里集成 ripgrep
VS Code 的内置搜索底层就使用 ripgrep,因此你在编辑器里按到的「搜索结果」天然支持 .gitignore 与类型过滤。若是 Neovim/Vim 用户,可用 telescope、fzf.vim 或 LeaderF 直接调用 rg 作为后端,获得和 IDE 一样顺滑的体验。JetBrains 系列也可在设置里把「使用 ripgrep 索引」勾上以加速 Find in Files。换句话说,学会 rg 等于同时学会了你所有编辑器的搜索语法。
九、在 CI 里做代码审计
ripgrep 的 --files-with-matches 与非零退出码让它能直接当「代码门禁」。在 GitHub Actions 里拦住敏感信息或 TODO 残留非常方便:
# 在 CI 中禁止提交包含明文密钥
if rg -l --no-ignore -e "AKIA[0-9A-Z]{16}" -e "sk-[a-zA-Z0-9]{20}"; then
echo "发现疑似密钥,阻断提交"
exit 1
fi
这种「提交前扫描」比事后在代码平台补救便宜得多:一条几行的 workflow 就能把明文密钥、debug 开关、todo 标记挡在合并之前,且因为 rg 极快,即使在超大仓库里也只是多花几百毫秒。
十、结合 Git 只搜被跟踪文件
配合 Git 内部原理 的认知,ripgrep 默认已经通过 .git 目录判断仓库边界。想严格只搜「被 git 跟踪」的文件,可用 git ls-files 喂给 rg:
# 仅搜索 git 跟踪的文件
git ls-files | rg -t py "TODO"
# 跨分支搜索某次提交引入的关键字
git grep "TODO" $(git rev-list --all) | head
十一、在 Docker 容器里用 rg
在 Docker 里排障时,容器往往没有顺手的搜索工具。最轻量的办法是把宿主机的 rg 二进制挂进去,或用多阶段构建把 rg 拷进最终镜像:
# 临时把宿主机 rg 挂进容器使用
docker run --rm -v "$(which rg):/usr/local/bin/rg" -v "$PWD:/app" -w /app myimage rg -t py TODO
# 多阶段构建:从基础镜像拷贝 rg 二进制
FROM rust:1-slim AS build
RUN cargo install ripgrep
FROM gcr.io/distroless/base
COPY --from=build /usr/local/cargo/bin/rg /usr/bin/rg
十二、性能原理:为什么这么快
ripgrep 的快不是玄学,主要来自四点:① 并行目录遍历,多个线程同时扫不同子树;② 默认遵守 .gitignore,直接跳过 node_modules 这类巨型目录,IO 量骤减;③ 内存映射 + SIMD 加速的字节匹配,配合 Rust 的 regex 引擎做字面量优化;④ 智能忽略隐藏/二进制文件,避免无意义的编码探测。正是这些默认决策,让它在真实仓库里比裸 grep 快一个数量级。值得一提的是,它的正则引擎在遇到纯字面量时会自动降级为更高效的字符串搜索,所以「搜一个固定词」比「搜一个复杂正则」还要快。
十三、ripgrep 的局限:何时仍该用 grep
ripgrep 并非万能。当你需要跨多文件的大段上下文、复杂的 Perl 兼容正则(-P)、或必须在没有 Rust 二进制的最小容器/嵌入式环境里搜索时,grep 仍不可替代。另外 rg 默认不搜隐藏文件(如 .env),若忘了加 --hidden 可能漏掉配置文件,这是最常见的「搜不到」误区。最佳实践是把 rg 当日常主力,遇到上述边界场景再退回 grep,而不是二选一。
十四、常见问题排查
| 现象 | 可能原因 | 解决 |
|---|---|---|
| 搜不到明明存在的字符串 | 被 .gitignore 忽略 | 加 -u 或 –no-ignore 放宽 |
| 匹配到二进制文件乱码 | 未跳过二进制 | 加 –no-binary(默认已跳过) |
| 想搜隐藏目录配置 | 默认 -hidden 关闭 | 加 –hidden 并在 rc 配置 |
| 中文正则不生效 | locale 未设 UTF-8 | export LANG=en_US.UTF-8 |
十五、总结
ripgrep 用一个「默认就做对」的设计,把代码搜索这件小事做到了极致:安装一行命令,使用零配置,速度碾压 grep。把它和 fzf、Git、CI、编辑器串起来后,你的「找代码」效率会彻底跃迁。今天就可以在终端敲下 brew install ripgrep,然后试着用 rg -t py TODO 搜一遍你的项目——相信我,你再也回不去 grep 了。




