ripgrep:基于 Rust 技术的命令行文本搜索工具项目

ripgrep recursively searches directories for a regex pattern while respecting your gitignore

Branch16Tags270
FilesLast commitLast update
2 years ago
1 month ago
3 years ago
2 months ago
1 month ago
11 months ago
1 month ago
7 years ago
1 month ago
1 month ago
3 years ago
1 month ago
3 months ago
1 month ago
2 months ago
10 years ago
1 month ago
1 month ago
11 months ago
3 months ago
9 years ago
10 years ago
1 month ago
10 months ago
10 years ago
11 months ago
11 months ago

ripgrep (rg)

ripgrep 是一款面向行的搜索工具,它能在当前目录下递归搜索正则表达式模式。默认情况下,ripgrep 会遵循 gitignore 规则,并自动跳过隐藏文件/目录和二进制文件。(若要默认禁用所有自动过滤功能,请使用 rg -uuu。)ripgrep 在 Windows、macOS 和 Linux 系统上均提供一流支持,每个版本的二进制文件可从 发布页面 下载。ripgrep 与其他热门搜索工具(如 The Silver Searcher、ack 和 grep)类似。

构建状态 Crates.io 打包状态

采用 MIT 许可证或 UNLICENSE 双重许可。

变更日志

发布历史请参见 CHANGELOG

文档快速链接

搜索结果截图

ripgrep 示例搜索截图

工具对比快速示例

本示例在整个 Linux 内核源代码树(运行 make defconfigconfig && 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。ugrep 的时间不受 -n 存在与否的影响。

不过,请注意性能突变点:

工具 命令 行数 时间
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 8分30秒 (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(始终启用)的同时保持了快速的速度。
  • ripgrep 可选支持将其正则表达式引擎切换为使用 PCRE2。除其他功能外,这使得在模式中使用环视和反向引用成为可能,而这些在 ripgrep 的默认正则表达式引擎中不受支持。可以使用 -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 添加所有功能,但随着时间的推移,ripgrep 已经支持了其他文件搜索工具中的大多数功能。这包括跨多行搜索结果,以及可选的 PCRE2 支持,后者提供环视和反向引用功能。

目前,不使用 ripgrep 的主要原因可能包括以下一个或多个:

  • 你需要一个便携且普遍存在的工具。虽然 ripgrep 可在 Windows、macOS 和 Linux 上运行,但它并非随处可见,也不符合任何标准(如 POSIX)。这类工作的最佳工具还是经典的 grep。
  • 存在本 README 中未列出的某些其他功能(或 bug),而你依赖的其他工具具备这些功能,但 ripgrep 没有。
  • 在某些性能边缘情况下,ripgrep 的表现不佳,而其他工具却能应对。(请提交错误报告!)
  • 无法在你的机器上安装 ripgrep,或者它不支持你的平台。(请提交错误报告!)

它真的比其他所有工具都快吗?

通常来说,是的。我的博客上提供了大量基准测试以及针对每个测试的详细分析:available on my blog

总而言之,ripgrep 之所以快速,原因如下:

  • 它基于 Rust's regex engine 构建。Rust 的正则表达式引擎使用有限自动机、SIMD 和积极的文本优化,使搜索速度非常快。(可通过 -P/--pcre2 标志选择启用 PCRE2 支持。)
  • Rust 的正则表达式库通过将 UTF-8 解码直接构建到其确定性有限自动机引擎中,在提供完整 Unicode 支持的同时保持了高性能。
  • 它支持使用内存映射或通过中间缓冲区进行增量搜索。前者更适合单个文件,后者更适合大型目录。ripgrep 会自动为你选择最佳的搜索策略。
  • 使用 RegexSet 应用 .gitignore 文件中的忽略模式。这意味着可以同时将单个文件路径与多个 glob 模式进行匹配。
  • 它使用无锁并行递归目录迭代器,这得益于 crossbeamignore

功能对比

ack 的作者 Andy Lester 发布了一份出色的表格,对比了 ack、ag、git-grep、GNU grep 和 ripgrep 的功能:https://beyondgrep.com/feature-comparison/

需要注意的是,ripgrep 最近新增了一些重要功能,这些功能尚未收录到 Andy 的表格中。其中包括但不限于:配置文件、passthru 模式、压缩文件搜索支持、多行搜索以及通过 PCRE2 实现的可选高级正则表达式支持。

在线体验

如果您想在安装前试用 ripgrep,可以访问非官方的 playground交互式教程

如果您对这些有任何疑问,请在 tutorial repo 中提交 issue。

安装

ripgrep 的二进制文件名称为 rg

ripgrep 的预编译二进制文件归档可用于 Windows、macOS 和 Linux。 Linux 和 Windows 二进制文件是静态可执行文件。对于以下未明确提及的平台用户,建议下载这些归档文件之一。

如果您是 macOS HomebrewLinuxbrew 用户,可以通过 homebrew-core 安装 ripgrep:

$ brew install ripgrep

如果你是 MacPorts 用户,那么你可以从 官方端口 安装 ripgrep:

$ sudo port install ripgrep

如果你是 Windows Chocolatey 用户,可以从 official repo 安装 ripgrep:

$ choco install ripgrep

如果你是 Windows Scoop 用户,可以通过 official 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 TumbleweedopenSUSE 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 release 中提供的二进制 .deb 文件来安装 ripgrep。

$ 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,ripgrep 由 Debian 官方维护,不过其版本可能比上一步中提供的 deb 包要旧。

$ sudo apt-get install ripgrep

如果你是 Ubuntu Cosmic (18.10)(或更新版本)用户,ripgrep 可通过与 Debian 相同的打包方式获取,具体可参见 此处

$ 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用户,那么可以通过官方端口安装ripgrep:

$ sudo pkgman install ripgrep

如果您是 Haiku x86_gcc2 用户,可以通过 x86 次要架构构建,从与 Haiku x86_64 相同的端口安装 ripgrep:

$ sudo pkgman install ripgrep_x86

如果你是 Void Linux 用户,那么可以从官方仓库安装 ripgrep:

$ sudo xbps-install -Syv ripgrep

如果你是一名Rust 程序员,可以使用 cargo 安装 ripgrep。

  • 请注意,ripgrep 支持的最低 Rust 版本为 1.96.0,不过旧版本 Rust 也可能可以运行 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

注意: 过去,当使用 Rust nightly 编译器时,ripgrep 支持 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 目标构建 ripgrep:首先在系统上安装 MUSL 库(请咨询您常用的软件包管理器)。然后,只需向 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 文档翻译列表。这些翻译为非官方维护,可能不是最新版本。

Introduction

Ripgrep 递归地在目录中搜索正则表达式模式,同时遵守您的 gitignore 规则。【此简介由AI生成】

Customize your domain
31668.21 K2.76 KVisit GitHub