关于 ripgrep
ripgrep(rg)是一个快速的文件搜索工具,支持递归目录搜索、正则表达式匹配和 gitignore 集成。通过 rg "TODO" 搜索文本、rg --files 列出项目文件、rg -t ts 指定文件类型搜索。
主要功能
- 01使用正则表达式递归搜索目录中的文本模式
- 02列出项目中的所有文件,自动尊重 gitignore 规则
- 03按文件类型过滤搜索结果,提高搜索精度
适用场景
- 01编码 Agent 快速定位代码中的特定模式或 TODO 标记
- 02开发者在大型代码库中搜索函数、API 调用或配置值
- 03在项目文件系统中查找需要重构或更新的代码段
安装
选择你的系统或包管理器,复制命令到终端运行。
安装完成后运行rg --version确认安装成功。
命令示例
常用命令按使用顺序排列。
详细介绍
ripgrep (rg)
ripgrep 是一款面向行的搜索工具,可在当前目录中递归搜索正则表达式模式。默认情况下,ripgrep 会遵循 gitignore 规则,并自动跳过隐藏文件/目录和二进制文件。(如要默认禁用所有自动过滤,请使用 rg -uuu。)ripgrep 对 Windows、macOS 和 Linux 均提供一流支持,并且可从每个版本下载二进制文件。ripgrep 与 The Silver Searcher、ack 和 grep 等其他热门搜索工具类似。
采用 MIT 或 UNLICENSE 双重许可。
更新日志
请参阅 CHANGELOG 了解版本发布历史。
文档快速链接
搜索结果截图
工具对比快速示例
此示例在整个 Linux 内核源代码树(运行 make defconfig && make -j8 后)中搜索 [A-Z]+_SUSPEND,并要求所有匹配项都是单词。计时是在配备 Intel i9-12900K 5.2 GHz 的系统上采集的。
请记住,单次基准测试永远不足以说明问题!请参阅我的 ripgrep 博文,其中包含非常详细的对比、更多基准测试和分析。
| 工具 | 命令 | 行数 | 时间 |
|---|---|---|---|
| ripgrep(Unicode) | rg -n -w '[A-Z]+_SUSPEND' | 536 | 0.082s (1.00x) |
| hypergrep | hgrep -n -w '[A-Z]+_SUSPEND' | 536 | 0.167s (2.04x) |
| git grep | git grep -P -n -w '[A-Z]+_SUSPEND' | 536 | 0.273s (3.34x) |
| The Silver Searcher | ag -w '[A-Z]+_SUSPEND' | 534 | 0.443s (5.43x) |
| ugrep | ugrep -r --ignore-files --no-hidden -I -w '[A-Z]+_SUSPEND' | 536 | 0.639s (7.82x) |
| git grep | LC_ALL=C git grep -E -n -w '[A-Z]+_SUSPEND' | 536 | 0.727s (8.91x) |
| git grep(Unicode) | LC_ALL=en_US.UTF-8 git grep -E -n -w '[A-Z]+_SUSPEND' | 536 | 2.670s (32.70x) |
| ack | ack -w '[A-Z]+_SUSPEND' | 2677 | 2.935s (35.94x) |
以下是在同一语料库上进行的另一项基准测试:忽略 gitignore 文件,改用白名单进行搜索。语料库与上一个基准测试相同,各命令传入的标志确保它们执行的工作相当:
| 工具 | 命令 | 行数 | 时间 |
|---|---|---|---|
| ripgrep | rg -uuu -tc -n -w '[A-Z]+_SUSPEND' | 447 | 0.063s (1.00x) |
| ugrep | ugrep -r -n --include='*.c' --include='*.h' -w '[A-Z]+_SUSPEND' | 447 | 0.607s (9.62x) |
| GNU grep | grep -E -r -n --include='*.c' --include='*.h' -w '[A-Z]+_SUSPEND' | 447 | 0.674s (10.69x) |
现在,我们将转向在单个大文件中搜索。以下是 ripgrep、ugrep 和 GNU grep 在一个缓存于内存中的文件(约 13GB,解压后的 OpenSubtitles.raw.en.gz)上的直接对比: |
| 工具 | 命令 | 行数 | 时间 |
|---|---|---|---|
| ripgrep(Unicode) | rg -w 'Sherlock [A-Z]\w+' | 7882 | 1.042s(1.00x) |
| ugrep | ugrep -w 'Sherlock [A-Z]\w+' | 7882 | 1.339s(1.28x) |
| GNU grep(Unicode) | LC_ALL=en_US.UTF-8 egrep -w 'Sherlock [A-Z]\w+' | 7882 | 6.577s(6.31x) |
在上述基准测试中,传入 -n 标志(用于显示行号)后,ripgrep 的耗时增至 1.664s,GNU grep 则增至 9.484s。无论是否传入 -n,ugrep 的耗时都不受影响。
不过,请注意性能断崖:
| 工具 | 命令 | 行数 | 时间 |
|---|---|---|---|
| ripgrep(Unicode) | rg -w '[A-Z]\w+ Sherlock [A-Z]\w+' | 485 | 1.053s(1.00x) |
| GNU grep(Unicode) | LC_ALL=en_US.UTF-8 grep -E -w '[A-Z]\w+ Sherlock [A-Z]\w+' | 485 | 6.234s(5.92x) |
| ugrep | ugrep -w '[A-Z]\w+ Sherlock [A-Z]\w+' | 485 | 28.973s(27.51x) |
如果在大文件中搜索没有任何字面量优化机会的模式,整体性能也可能急剧下降:
| 工具 | 命令 | 行数 | 时间 |
|---|---|---|---|
| ripgrep | rg '[A-Za-z]{30}' | 6749 | 15.569s(1.00x) |
| ugrep | ugrep -E '[A-Za-z]{30}' | 6749 | 21.857s(1.40x) |
| GNU grep | LC_ALL=C grep -E '[A-Za-z]{30}' | 6749 | 32.409s(2.08x) |
| GNU grep(Unicode) | LC_ALL=en_US.UTF-8 grep -E '[A-Za-z]{30}' | 6795 | 8m30s(32.74x) |
最后,匹配数量很大时,性能通常也会大幅下降,而且工具间的差距会缩小(一般来说,这是因为性能主要取决于处理匹配项的速度,而非用于检测匹配项的算法):
| 工具 | 命令 | 行数 | 时间 |
|---|---|---|---|
| ripgrep | rg the | 83499915 | 6.948s(1.00x) |
| ugrep | ugrep the | 83499915 | 11.721s(1.69x) |
| GNU grep | LC_ALL=C grep the | 83499915 | 15.217s(2.19x) |
为什么要使用 ripgrep?
- 它可以替代其他搜索工具的许多用法,因为它包含了大部分相关功能,而且通常速度更快。(关于 ripgrep 是否真的能替代 grep 的更多详情,请参阅常见问题。)
- 与其他专用于代码搜索的工具一样,ripgrep 默认进行递归搜索,并会自动过滤。具体来说,ripgrep 不会搜索被
.gitignore/.ignore/.rgignore文件忽略的文件,不会搜索隐藏文件,也不会搜索二进制文件。可使用rg -uuu禁用自动过滤。 - ripgrep 可以搜索特定类型的文件。例如,
rg -tpy foo会将搜索范围限制为 Python 文件,而rg -Tjs foo会将 JavaScript 文件排除在搜索范围之外。还可以通过自定义匹配规则,让 ripgrep 识别新的文件类型。 - ripgrep 支持
grep中的许多功能,例如显示搜索结果的上下文、搜索多个模式、用颜色突出显示匹配项,以及完整的 Unicode 支持。与 GNU grep 不同,ripgrep 在支持 Unicode 的同时仍能保持快速(Unicode 始终启用)。 - ripgrep 可以选择切换正则表达式引擎,使用 PCRE2。除此之外,这使你可以在模式中使用默认正则表达式引擎不支持的环视和反向引用。可使用
-P/--pcre2(始终使用 PCRE2)或--auto-hybrid-regex(仅在需要时使用 PCRE2)启用 PCRE2 支持。也可以通过--engine (default|pcre2|auto)选项使用另一种语法。 - ripgrep 对替换提供了基础支持,可根据匹配内容改写输出。
- ripgrep 支持搜索采用 UTF-8 以外文本编码的文件,例如 UTF-16、latin-1、GBK、EUC-JP、Shift_JIS 等。(它能在一定程度上自动检测 UTF-16。其他文本编码必须通过
-E/--encoding标志明确指定。) - ripgrep 支持使用
-z/--search-zip标志搜索采用常见格式(brotli、bzip2、gzip、lz4、lzma、xz 或 zstandard)压缩的文件。 - ripgrep 支持任意输入预处理过滤器,可用于提取 PDF 文本、解压支持范围有限的格式、解密、自动检测编码等。
- ripgrep 可以通过配置文件进行配置。
换句话说,如果你看重速度、默认过滤、更少的错误和 Unicode 支持,就使用 ripgrep。
为什么不应该使用 ripgrep?
尽管 ripgrep 最初并不打算囊括所有功能,但随着时间推移,它逐渐支持了其他文件搜索工具中的大多数功能。这包括搜索跨越多行的结果,以及选择启用 PCRE2 支持,从而提供环视和反向引用功能。
目前,不使用 ripgrep 的主要原因可能包括以下一项或多项:
- 你需要一个可移植且无处不在的工具。ripgrep 虽然可以在 Windows、macOS 和 Linux 上运行,但并非无处不在,也不符合 POSIX 等任何标准。完成这项工作的最佳工具是经典的 grep。
- 你依赖其他工具中的某项功能(或修复了某个问题),但该功能(或问题)未在本 README 中列出,而且 ripgrep 不支持。
- 存在某种性能边界情况,导致 ripgrep 表现不佳,而其他工具表现良好。(请提交错误报告!)
- 无法在你的计算机上安装 ripgrep,或者它不支持你的平台。(请提交错误报告!)
它真的比其他所有工具都快吗?
通常是的。我的博客上提供了大量基准测试,并对每项测试进行了详细分析。
总的来说,ripgrep 速度很快,原因如下:
- 它基于
Rust 的正则表达式引擎构建。
Rust 的正则表达式引擎使用有限自动机、SIMD 和激进的字面量优化来实现非常快速的搜索。(可以通过
-P/--pcre2标志选择启用 PCRE2 支持。) - Rust 的正则表达式库通过将 UTF-8 解码直接集成到其确定性有限自动机引擎中,在全面支持 Unicode 的同时保持了性能。
- 它支持使用内存映射进行搜索,也支持使用中间缓冲区进行增量搜索。前者更适合单个文件,后者更适合大型目录。ripgrep 会自动为你选择最佳搜索策略。
- 它使用
RegexSet应用.gitignore文件中的忽略模式。 这意味着可以同时将单个文件路径与多个 glob 模式进行匹配。 - 它使用无锁的并行递归目录迭代器,这要归功于
crossbeam和ignore。
功能对比
ack 的作者 Andy Lester 发布了一张很棒的表格,对比了 ack、ag、git-grep、GNU grep 和 ripgrep 的功能:https://beyondgrep.com/feature-comparison/
请注意,ripgrep 最近新增了几项重要功能,Andy 的表格尚未收录。这些功能包括但不限于配置文件、passthru、支持搜索压缩文件、多行搜索,以及通过 PCRE2 选择启用的高级正则表达式支持。
在线体验
如果你想在安装前试用 ripgrep,可以使用非官方的在线体验环境和交互式教程。
如果你对这些内容有任何疑问,请在教程仓库中提交 issue。
安装
ripgrep 的二进制文件名是 rg。
可从此处下载适用于 Windows、macOS 和 Linux 的 ripgrep 预编译二进制文件压缩包。 Linux 和 Windows 的二进制文件都是静态可执行文件。未在下方明确列出平台的用户,建议下载其中一个压缩包。
如果你是 macOS Homebrew 或 Linuxbrew 用户,可以从 homebrew-core 安装 ripgrep:
$ brew install ripgrep
如果你是 MacPorts 用户,可以从官方 ports安装 ripgrep:
$ sudo port install ripgrep
如果你是 Windows Chocolatey 用户,可以从官方仓库安装 ripgrep:
$ choco install ripgrep
如果你是 Windows Scoop 用户,可以从官方 bucket安装 ripgrep:
$ scoop install ripgrep
如果你是 Windows Winget 用户,可以从 winget-pkgs 仓库安装 ripgrep:
$ winget install BurntSushi.ripgrep.MSVC
如果你是 Arch Linux 用户,可以从官方仓库安装 ripgrep:
$ sudo pacman -S ripgrep
如果你是 Gentoo 用户,可以从官方仓库安装 ripgrep:
$ sudo emerge sys-apps/ripgrep
如果你是 Fedora 用户,可以从官方仓库安装 ripgrep。
$ sudo dnf install ripgrep
如果你是 openSUSE 用户,ripgrep 已包含在 openSUSE Tumbleweed 和 openSUSE Leap 中,适用于 15.1 及更高版本。
$ sudo zypper install ripgrep
如果你是 CentOS Stream 10 用户,可以从 EPEL 仓库安装 ripgrep:
$ sudo dnf config-manager --set-enabled crb
$ sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm
$ sudo dnf install ripgrep
如果你是 Red Hat 10 用户,可以从 EPEL 仓库安装 ripgrep:
$ sudo subscription-manager repos --enable codeready-builder-for-rhel-10-$(arch)-rpms
$ sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm
$ sudo dnf install ripgrep
如果你是 Rocky Linux 10 用户,可以从 EPEL 仓库安装 ripgrep:
$ sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm
$ sudo dnf install ripgrep
如果你是 Nix 用户,可以从 nixpkgs 安装 ripgrep:
$ nix-env --install ripgrep
如果你是 Flox 用户,可以按如下方式安装 ripgrep:
$ flox install ripgrep
如果你是 Guix 用户,可以从官方软件包集合安装 ripgrep:
$ guix install ripgrep
如果你是 Debian 用户(或使用 Ubuntu 等 Debian 衍生发行版),可以使用每个 ripgrep 发行版提供的二进制 .deb 文件进行安装。
$ curl -LO https://github.com/BurntSushi/ripgrep/releases/download/14.1.1/ripgrep_14.1.1-1_amd64.deb
$ sudo dpkg -i ripgrep_14.1.1-1_amd64.deb
如果你使用 Debian stable,Debian 会官方维护 ripgrep,不过其版本可能早于上一步提供的 deb 软件包。
$ sudo apt-get install ripgrep
如果你是 Ubuntu Cosmic (18.10)(或更新版本)用户,可以使用与 Debian 相同的打包方式获取 ripgrep:
$ sudo apt-get install ripgrep
(注意:Ubuntu 上也有各种 ripgrep 的 snap,但它们似乎都无法正常工作,并会产生许多非常奇怪的错误报告,而我不知道如何修复,也没有时间处理。因此,不再建议使用这种安装方式。)
如果你是 ALT 用户,可以从官方仓库安装 ripgrep:
$ sudo apt-get install ripgrep
如果你是 FreeBSD 用户,可以从官方 ports安装 ripgrep:
$ sudo pkg install ripgrep
如果你是 OpenBSD 用户,可以从官方 ports安装 ripgrep:
$ doas pkg_add ripgrep
如果你是 NetBSD 用户,可以从 pkgsrc 安装 ripgrep:
$ sudo pkgin install ripgrep
如果你是 Haiku x86_64 用户,可以从官方 ports安装 ripgrep:
$ sudo pkgman install ripgrep
如果你是 Haiku x86_gcc2 用户,可以使用 x86 次要架构构建,从与 Haiku x86_64 相同的 port 安装 ripgrep:
$ sudo pkgman install ripgrep_x86
如果你是 Void Linux 用户,可以从官方仓库安装 ripgrep:
$ sudo xbps-install -Syv ripgrep
如果你是 Rust 程序员,可以使用 cargo 安装 ripgrep。
- 请注意,ripgrep 支持的最低 Rust 版本是 1.96.0,不过 ripgrep 可能也能在更旧的版本上运行。
- 请注意,二进制文件可能比预期更大,因为其中包含调试符号。这是有意为之。若要移除调试符号并缩小文件体积,请对二进制文件运行
strip。
$ cargo install ripgrep
或者,也可以使用 cargo binstall 直接从 GitHub 安装 ripgrep 二进制文件:
$ cargo binstall ripgrep
构建
ripgrep 使用 Rust 编写,因此需要先安装 Rust,才能编译它。 ripgrep 可使用 Rust 1.96.0(稳定版)或更高版本编译。通常,ripgrep 会跟进 Rust 编译器的最新稳定版本。
构建 ripgrep:
$ git clone https://github.com/BurntSushi/ripgrep
$ cd ripgrep
$ cargo build --release
$ ./target/release/rg --version
0.1.3
注意: 过去,ripgrep 在使用 Rust nightly 编译器时支持 simd-accel Cargo 功能。此功能仅对 UTF-16 转码有帮助。
由于它需要不稳定功能,这种构建模式容易出现问题。
因此,我们已移除对它的支持。如果你想为 UTF-16 转码启用 SIMD
优化,则需要向
encoding_rs 项目提出请求,促使其使用稳定
API。
最后,启用 pcre2 功能即可在构建 ripgrep 时加入可选的 PCRE2 支持:
$ cargo build --release --features 'pcre2'
启用 PCRE2 功能可使用稳定版 Rust 编译器,并会尝试通过
pkg-config 自动查找并链接系统中的 PCRE2 库。如果系统中没有该库,ripgrep 会使用
系统的 C 编译器从源代码构建 PCRE2,然后将其静态链接到最终的可执行文件中。即使系统中已有 PCRE2
库,也可以通过使用 MUSL 目标构建 ripgrep 或设置
PCRE2_SYS_STATIC=1 来强制静态链接。
在 Linux 上,先在系统中安装 MUSL 库(请咨询你常用的软件包管理器),即可使用 MUSL 目标构建 ripgrep。然后,只需为 Rust 工具链添加 MUSL 支持并重新构建 ripgrep,即可生成完全静态的可执行文件:
$ rustup target add x86_64-unknown-linux-musl
$ cargo build --release --target x86_64-unknown-linux-musl
如上所述,使用 --features 标志即可按预期启用功能。如果你想使用 MUSL 和 PCRE2
构建静态可执行文件,则需要安装 musl-gcc。根据你的 Linux 发行版,musl-gcc 可能与 MUSL
库本身分别打包。
运行测试
ripgrep 经过了较为充分的测试,包括单元测试和集成测试。要运行完整的测试套件,请在 仓库根目录中执行:
$ cargo test --all
相关工具
- delta 是一款支持
rg --json输出格式的语法高亮 分页器。只需运行rg --json pattern | delta即可使用。更多详情请参阅 delta 手册中关于 grep 的章节。
漏洞报告
如需报告安全漏洞,请 联系 Andrew Gallant。 联系页面上有我的电子邮件地址和 PGP 公钥,你可以用它们发送 加密消息。
翻译
以下是已知的 ripgrep 文档翻译列表。这些翻译均由非官方维护,可能不是最新版本。
