微信公众号二维码
本文已同步发布到微信公众号「人言兑
👈 扫描二维码关注,第一时间获取更新!

在软件开发与日常运维中,代码搜索是最频繁也最容易被忽视的效率瓶颈。传统的 grep 命令虽然经典,但在大型项目中往往显得力不从心——速度慢、需要手动排除目录、输出杂乱无章。

ripgrep (rg) 作为新一代命令行搜索工具,凭借grep 快 10~300 倍的极速性能默认遵守 .gitignore 的智能过滤以及人性化的彩色输出,成为了越来越多开发者、DevOps 和开源贡献者的首选。

本文将从详尽的功能对比、性能实测数据到实战技巧,详细介绍 ripgrep 的用法以及和 grep 的区别

rg 命令用法指南

ripgrep 简介

ripgrep(命令名 rg)是一个面向行的搜索工具,它会递归地搜索当前目录中的正则表达式模式。默认情况下,ripgrep 会遵循 .gitignore 规则,并自动跳过隐藏文件/目录和二进制文件。它可以在 Windows、macOS 和 Linux 上原生运行,速度极快,并提供了许多现代化特性。

主要特点:

  • 默认递归搜索 + 自动过滤(尊重 .gitignore/.ignore/.rgignore
  • 支持正则表达式,且默认开启 Unicode 支持
  • 可搜索特定类型的文件(如 -tpy 限定 Python 文件)
  • 支持上下文显示、高亮、多行匹配、替换输出
  • 可选 PCRE2 引擎(支持环视和反向引用)
  • 支持多种文件编码(UTF-16、GBK、EUC-JP 等)
  • 支持搜索压缩文件(gzip、bzip2、xz、zstd 等)
  • 可通过配置文件自定义默认参数
  • 并行搜索,性能优异

安装 ripgrep

ripgrep 各平台包管理器

macOS (Homebrew)

brew install ripgrep

Windows (Chocolatey)

choco install ripgrep

Windows (Scoop)

scoop install ripgrep

Windows (Winget)

winget install BurntSushi.ripgrep.MSVC

Arch Linux

sudo pacman -S ripgrep

Debian/Ubuntu(使用官方 .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

Fedora

sudo dnf install ripgrep

openSUSE

sudo zypper install ripgrep

FreeBSD

sudo pkg install ripgrep

Rust (Cargo)

cargo install ripgrep

源码编译

git clone https://github.com/BurntSushi/ripgrep
cd ripgrep
cargo build --release
./target/release/rg --version

启用 PCRE2 支持:

cargo build --release --features 'pcre2'

ripgrep 基本用法

rg [OPTIONS] PATTERN [PATH ...]

最简单示例:在当前目录所有文件中搜索 hello

rg hello

如果只想搜索特定文件:

rg hello README.md

从标准输入读取:

echo "hello world" | rg hello

默认行为

  • 递归搜索当前目录
  • 忽略 .gitignore 中的文件、隐藏文件和二进制文件
  • 打印匹配行的内容,并显示行号和文件名(颜色高亮)

ripgrep 递归搜索

默认情况下 rg pattern 就是递归搜索当前目录。你也可以显式指定目录:

rg hello ./src

如果要搜索整个系统并跟随符号链接:

rg hello / --follow

限制递归深度

rg hello --max-depth 2

只列出会被搜索的文件(不实际搜索):

rg --files

ripgrep 自动过滤

ripgrep 默认应用以下过滤规则:

  1. 忽略文件.gitignore.ignore.rgignore(包括父目录中的)
  2. 隐藏文件:以 . 开头的文件和目录
  3. 二进制文件:包含 NUL 字节的文件
  4. 符号链接:默认不跟随

你可以通过以下标志放松过滤:

标志效果
-u禁用 .gitignore 处理
-uu同时搜索隐藏文件
-uuu同时搜索二进制文件(相当于 -a
--no-ignore完全不使用任何忽略文件
--hidden (-.)搜索隐藏文件
--text (-a)把二进制文件当作文本搜索
--follow (-L)跟随符号链接

示例:搜索所有文件(包括隐藏和二进制)并跟随符号链接:

rg hello -uuuL

ripgrep 手动过滤

使用 glob 模式

-g 选项可以包含或排除匹配特定 glob 的文件。规则与 .gitignore 相同:后面的模式覆盖前面的。

只搜索 .rs 文件

rg hello -g '*.rs'

排除所有 .toml 文件

rg hello -g '!*.toml'

同时使用(先排除再包含,最终只搜索 .rs 文件):

rg hello -g '!*.toml' -g '*.rs'

忽略大小写的 glob:使用 --iglob 或在 .gitignore 中使用 --ignore-file-case-insensitive

使用文件类型

ripgrep 内置了许多常见文件类型,可以通过 --type-list 查看所有支持的类型。

只搜索 Rust 文件

rg hello -trust
# 等价于
rg hello --type rust

排除 JavaScript 文件

rg hello -Tjs

自定义类型

rg --type-add 'web:*.{html,css,js}' -tweb title

特殊类型 all:匹配所有内置类型(不包括自定义类型)。例如只搜索所有已知的文件类型:

rg hello --type all

要使自定义类型永久生效,可以将其加入配置文件或 shell 别名。

ripgrep 替换输出

注意:ripgrep 不会修改原始文件,仅修改输出。

基本替换:

rg fast README.md -r FAST

使用捕获组:

rg 'fast\s+(\w+)' README.md -r 'fast-$1'

使用命名捕获组:

rg 'fast\s+(?P<word>\w+)' README.md -r 'fast-$word'

只输出匹配部分并替换:

rg fast README.md -or FAST

ripgrep 配置文件

ripgrep 支持通过配置文件设置默认参数。设置环境变量 RIPGREP_CONFIG_PATH 指向配置文件。

export RIPGREP_CONFIG_PATH="$HOME/.ripgreprc"

配置文件格式:每行一个参数,# 开头的行是注释。带值的参数可用 = 连接或分两行。

示例 ~/.ripgreprc

# 设置最大列宽并显示预览
--max-columns=150
--max-columns-preview

# 添加自定义文件类型
--type-add
web:*.{html,css,js}

# 默认搜索隐藏文件
--hidden

# 排除 .git 目录
--glob=!.git/*

# 颜色配置
--colors=line:none
--colors=line:style:bold

# 智能大小写
--smart-case

命令行参数会覆盖配置文件中的同名设置。

若想临时禁止读取配置文件,使用 --no-config

ripgrep 文件编码

默认情况下,ripgrep 使用 --encoding auto。它会:

  • 假设文件是 ASCII 兼容编码(ASCII、Latin1、UTF-8)
  • 如果检测到 UTF-16 BOM,则自动转码为 UTF-8 后搜索
  • 否则按原始字节搜索(但不保证 Unicode 特性有效)

指定编码

rg hello -E utf-16

支持的编码来自 Encoding Standard

完全禁用编码处理(直接搜索原始字节):

rg hello -E none

禁用 Unicode 模式(使 . 匹配字节而非 Unicode 码点):

rg '(?-u:.)'

ripgrep 搜索二进制文件

ripgrep 默认跳过二进制文件。二进制文件定义为包含 NUL 字节的文件。

三种模式:

模式行为启用方式
默认检测到二进制则停止搜索,若已有匹配则警告默认
二进制模式继续搜索直到文件尾或首个匹配,但避免输出乱码--binary
文本模式完全禁用二进制检测,所有文件按文本处理-a / --text

若要强制搜索二进制文件但不输出乱码:

rg hello --binary some-binary-file

ripgrep 预处理器(Preprocessor)

通过 --pre 可以指定一个外部命令,对每个文件进行预处理(如将 PDF 转为文本)后再搜索。

示例:搜索 PDF 文件

创建脚本 pdf2txt

#!/bin/sh
exec pdftotext - -

使用:

rg --pre ./pdf2txt 'pattern' document.pdf

只对特定文件类型启用预处理器(避免对所有文件都调用):

rg --pre ./pdf2txt --pre-glob '*.pdf' 'pattern'

更健壮的脚本示例(根据文件扩展名或 file 命令决定是否处理):

#!/bin/sh
case "$1" in
*.pdf)
    if [ -s "$1" ]; then
        exec pdftotext - -
    else
        exec cat
    fi
    ;;
*.zst)
    exec pzstd -cdq
    ;;
*)
    exec cat
    ;;
esac

ripgrep 常用选项速查

以下是最常用、最实用的选项:

选项说明
-i / --ignore-case忽略大小写
-S / --smart-case智能大小写(模式含大写则大小写敏感,否则不敏感)
-F / --fixed-strings将模式视为纯文本(不解释正则)
-w / --word-regexp匹配整个单词
-c / --count只输出每个文件匹配的行数
-l / --files-with-matches只输出包含匹配的文件名
-L只输出不包含匹配的文件名
-v / --invert-match反选(输出不匹配的行)
-U / --multiline多行匹配(默认识别换行)
-z / --search-zip搜索压缩文件(gzip、bzip2、xz、zstd 等)
-C<NUM> / --context=NUM显示匹配行上下各 NUM 行
-B<NUM> / --before-context=NUM显示匹配行之前的 NUM 行
-A<NUM> / --after-context=NUM显示匹配行之后的 NUM 行
-M<NUM> / --max-columns=NUM限制打印行的最大长度
-m<NUM> / --max-count=NUM每个文件最多匹配 NUM 次
-j<NUM> / --threads=NUM使用 NUM 个线程(默认并行)
--sort path按文件路径排序输出(会禁用并行)
-p / --pretty等价于 --color always --heading --line-number
--vimgrep输出格式兼容 vim 的 :vimgrep
--json以 JSON Lines 格式输出结果
--stats输出统计信息(匹配数、搜索时间等)
--debug显示调试信息(用于排查过滤问题)

ripgrep 正则表达式语法

ripgrep 默认使用 Rust 的正则引擎,语法文档:
https://docs.rs/regex/1.12.3/regex/#syntax

支持的特性

  • 标准 Perl 类正则
  • Unicode 字符类(\pL\p{Greek} 等)
  • 非贪婪量词(*?+?
  • 零宽断言(^$\b\B
  • 非捕获分组 (?:...)

不支持(默认引擎):

  • 反向引用(如 \1
  • 环视(lookahead/lookbehind)

启用 PCRE2 后支持(使用 -P--engine pcre2):

  • 反向引用
  • 环视((?=...)(?!...)(?<=...)(?<!...)
  • 其他 PCRE 特性

常用正则技巧

匹配 Unicode 字母

rg '\pL+' file

匹配 Email 地址(简版)

rg '\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b' file

多行匹配(需 -U):

rg -U 'function\s+\w+\([^)]*\)\s*\{[^}]*\}' file
# 小心:大括号嵌套会导致不完整,可用 PCRE2 递归匹配
rg -P -U 'function\s+\w+\([^)]*\)\s*\{(?:[^{}]|(?R))*\}' file

匹配空行

rg '^$'

ripgrep 常见问题

ripgrep 配置文件和自动补全

  • 配置文件:见上文“配置文件”一节。
  • Shell 自动补全:使用 rg --generate complete-<shell>,例如:
    rg --generate complete-bash > /etc/bash_completion.d/rg
    

ripgrep 如何对结果排序

默认并行搜索导致输出顺序不确定。若要稳定排序:

rg hello --sort path

这会强制单线程并按文件路径排序。

ripgrep 如何搜索压缩文件

使用 -z 标志:

rg -z 'pattern' log.gz

支持格式:gzip、bzip2、xz、lzma、lz4、brotli、zstd。需要系统中安装对应的解压工具(如 gzip 等)。

ripgrep 多行匹配

使用 -U 启用多行模式。注意:匹配可能会跨越巨大的范围,影响内存使用。

PCRE2 性能

PCRE2 通常较慢,因需逐行搜索(避免匹配跨行)且默认启用 Unicode 转码。为获得最佳 PCRE2 性能(不介意丢失 Unicode 和多行匹配),可尝试:

rg -P -U --no-pcre2-unicode 'pattern'

颜色配置

通过 --colors 定制颜色,格式:--colors '{type}:{attribute}:{value}'

  • type: path, line, column, match
  • attribute: fg, bg, style
  • value: 颜色名、0-255 数字、RGB(如 0x33,0x66,0xFF)或样式(bold, underline 等)

示例:模仿 The Silver Searcher 输出风格

rg --colors line:fg:yellow \
   --colors line:style:bold \
   --colors path:fg:green \
   --colors path:style:bold \
   --colors match:fg:black \
   --colors match:bg:yellow \
   --colors match:style:nobold \
   foo

ripgrep 与 grep 的关系

ripgrep 并非 100% 兼容 POSIX grep,但在大多数代码搜索场景下可以替代 grep。在某些便携性要求高的环境中(如脚本),仍应使用标准 grep

“rip” 的含义

原名 repxrepripgrep。“rip” 意为“快速翻阅”(to rip through text),而非“Rest in Peace”。尽管后者常被解读为“杀死 grep”,但并非原作者本意。

ripgrep 补充技巧

ripgrep 忽略大小写但保留高亮

默认 -i 会高亮匹配到的原文(可能大小写不同)。没问题。

ripgrep 只打印匹配的部分(不打印整行)

rg -o 'pattern'

显示匹配的字节偏移

rg -b pattern

递归搜索但不遵循符号链接(默认就是)

无需额外参数。

ripgrep 限制搜索的文件大小

rg pattern --max-filesize 50M

ripgrep 将搜索结果导入 vim

vim -q <(rg pattern --vimgrep)

或在 vim 中直接使用 :copen 配合 :grep 设置。

使用 findrg 组合

如果你需要更精细的文件选择,可以先用 find 输出文件列表,再用 rg 搜索:

find . -name "*.py" -exec rg pattern {} +

但通常 rg -g 就足够了。

获取帮助


也可以看看