文本搜索神器rg的使用教程
在大型工程项目中,传统的 grep 命令往往因性能瓶颈而显得力不从心。虽然 Ack 和 Ag (The Silver Searcher) 曾是优秀的替代品,但由 Rust 编写的 Ripgrep (rg) 凭借其卓越的性能和智能的默认配置,已成为现代开发者的首选搜索工具。
1. 工具介绍
Ripgrep (rg) 是一个面向行的搜索工具,旨在递归地在当前目录中搜索正则表达式模式。
1.1 核心特性
Ripgrep 的设计哲学是 “ 智能且快速 “。它默认启用了一系列符合开发者直觉的优化策略:
- 智能过滤:自动读取
.gitignore文件,忽略被排除的文件和隐藏文件。 - 自动递归:无需像 grep 那样指定
-R参数。 - 高性能:基于 Rust 开发,利用多线程和 SIMD 加速,显著快于 grep、ack 和 ag。
- 多格式支持:支持 UTF-8、UTF-16、GBK 等多种编码,以及 gzip、xz 等压缩文件。
- 类型过滤:支持按文件类型(如 python, js)进行搜索或排除。
1.2 搜索流程可视化
下图展示了 Ripgrep 的默认文件处理逻辑,这也是其高性能的关键原因之一:
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#4F46E5', 'primaryTextColor': '#fff', 'primaryBorderColor': '#3730A3', 'lineColor': '#6366F1', 'secondaryColor': '#10B981', 'tertiaryColor': '#F59E0B'}}}%%
flowchart TD
Start["开始搜索"] --> Scan["扫描目录"]
Scan --> CheckIgnore{"读取 .gitignore"}
CheckIgnore -->|"匹配忽略规则"| Skip["跳过文件"]
CheckIgnore -->|"未忽略"| CheckBinary{"检查二进制"}
CheckBinary -->|"是二进制文件"| Skip
CheckBinary -->|"是文本文件"| Match{"正则匹配内容"}
Match -->|"匹配成功"| Output["高亮输出"]
Match -->|"无匹配"| Next["下一个文件"]
classDef primary fill:#4F46E5,stroke:#3730A3,color:#fff
classDef skip fill:#9CA3AF,stroke:#4B5563,color:#fff
classDef success fill:#10B981,stroke:#059669,color:#fff
class Start,Scan,Match primary
class Skip skip
class Output success1.3 进阶工具:rga
对于 PDF、E-Books、Office 文档等非纯文本文件,推荐使用 ripgrep-all (rga) 作为补充工具。
2. 安装与配置
MacOS 用户推荐使用 Homebrew 安装:
1 | brew install ripgrep |
建议配置别名以简化操作:
1 | # 在 .zshrc 或 .bashrc 中添加 |
3. 实战指南
3.1 基础搜索
假设当前目录下有文件 example.txt:
1 | test |
默认搜索:
1
2rg 'test'
# 输出包含 test 的行,自动高亮全词匹配 (
-w):1
2rg -w 'test'
# 仅匹配单词 test,不匹配 testing忽略大小写 (
-i):1
2rg -i 'test'
# 匹配 test, TestCase, testing仅显示文件名 (
-l):1
2rg -l 'test'
# 输出: example.txt显示上下文 (
-C):1
2rg -C 2 'test'
# 显示匹配行及其前后各 2 行
3.2 高级过滤
Ripgrep 的强大之处在于其灵活的过滤机制。
指定文件类型 (
-t):1
2rg -t py 'import os' # 仅在 Python 文件中搜索
rg -T js 'function' # 排除 JS 文件Tip: 使用
rg --type-list查看支持的所有文件类型。穿透过滤规则 (
-u):
默认情况下 rg 会忽略隐藏文件和 gitignore 规则。若需强制搜索:1
2
3rg -u 'secret' # 不忽略 .gitignore
rg -uu 'secret' # 不忽略 .gitignore 和隐藏文件
rg -uuu 'secret' # 不忽略所有限制(包括二进制文件)正则搜索 (
-e):1
2rg -e "log.*error" -e "warn"
# 搜索匹配正则表达式的内容
3.3 文件名查找模式
rg 也可以作为 find 命令的高效替代品,用于查找文件路径:
1 | # 列出当前目录下所有将被搜索的文件(遵循 gitignore 规则) |
3.4 常用选项
展示一些最重要和最常用的选项,这些选项可能会影响您定期使用 ripgrep 的方式。
| 名 | 曰 |
|---|---|
-h | 显示 ripgrep 的浓缩帮助输出。 |
--help | 显示 ripgrep 的更长形式的帮助输出。(几乎是你在 ripgrep 的 man 页面里找到的,所以把它变成一个传呼机!) |
-i/--ignore-case | 当搜索模式时,忽略案例差异。那就是 rg -i fast 匹配 fast,fASt,FAST 等。 |
-S/--smart-case | 这类似于 --ignore-case 但如果模式包含大写字母,则禁用它自己。通常将此标志放入别名或配置文件中。 |
-w/--word-regexp | 要求图案的所有匹配都被单词边界包围。也就是说,给出 pattern, the --word-regexp 标志会使 ripgrep 表现得像 pattern 实际上是 \b(?:pattern)\b。 |
-c/--count | 报告总匹配行的计数。 |
--files | 打印 ripgrip _ 将要 _ 搜索的文件,但不要实际搜索它们。 |
-a/--text | 搜索二进制文件,就好像它们是纯文本一样。 |
-z/--search-zip | 搜索压缩文件 (gzip, bzip2, lzma, xz, lz4, brotli, zstd)。默认情况下这是禁用的。 |
-C/--context | 显示匹配周围的行。 |
--sort path | 强制 ripgrep 将其输出按文件名排序。(这禁用并行性,所以它可能会慢一些。) |
-L/--follow | 在递归搜索的同时,遵循符号链接。 |
-M/--max-columns | 限制 ripgrip 打印的行的长度。 |
--debug | 显示 ripgrip 的调试输出。这对于理解为什么在搜索中可以忽略特定文件,或者 ripgrep 正在从环境中加载何种配置非常有用。 |
4. 编辑器集成
4.1 Vim/Neovim 集成
配合 fzf.vim 插件,可以在 Vim 中实现极致的搜索体验。
配置示例:
1 | Plug 'junegunn/fzf', { 'do': { -> fzf#install() } } |
使用 :Rg 命令即可触发交互式搜索窗口,实时预览搜索结果。
