
在软件开发与日常运维中,代码搜索是最频繁也最容易被忽视的效率瓶颈。传统的 grep 命令虽然经典,但在大型项目中往往显得力不从心——速度慢、需要手动排除目录、输出杂乱无章。
而 ripgrep (rg) 作为新一代命令行搜索工具,凭借比 grep 快 10~300 倍的极速性能、默认遵守 .gitignore 的智能过滤以及人性化的彩色输出,成为了越来越多开发者、DevOps 和开源贡献者的首选。
本文将从详尽的功能对比、性能实测数据到实战技巧,详细介绍 ripgrep 的用法以及和 grep 的区别。
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 默认应用以下过滤规则:
- 忽略文件:
.gitignore、.ignore、.rgignore(包括父目录中的) - 隐藏文件:以
.开头的文件和目录 - 二进制文件:包含
NUL字节的文件 - 符号链接:默认不跟随
你可以通过以下标志放松过滤:
| 标志 | 效果 |
|---|---|
-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,matchattribute:fg,bg,stylevalue: 颜色名、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” 的含义
原名 rep → xrep → ripgrep。“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 设置。
使用 find 和 rg 组合
如果你需要更精细的文件选择,可以先用 find 输出文件列表,再用 rg 搜索:
find . -name "*.py" -exec rg pattern {} +
但通常 rg -g 就足够了。
获取帮助
- 简要帮助:
rg -h - 完整帮助(类似 man 页面):
rg --help - 生成 man 页面:
rg --generate man | man -l - - 项目主页: https://github.com/BurntSushi/ripgrep
完







