首页
/ ripgrep 用户指南深度实战:从逐行正则搜索到忽略过滤、类型过滤、替换与二进制文件处理

ripgrep 用户指南深度实战:从逐行正则搜索到忽略过滤、类型过滤、替换与二进制文件处理

2026-09-04 23:03:54作者:昌雅子Ethen

本文基于 ripgrep 官方用户指南 GUIDE.md 逐章展开,覆盖 ripgrep 的核心工作流:逐行模式匹配与正则语法、递归目录搜索、自动/手动过滤、输出替换、配置文件、文件编码、二进制文件三态处理以及 --pre 预处理器机制。读完本文后,你不仅能完整掌握 ripgrep 的常用参数与操作手法,还能对照 crates/core/search.rscrates/core/flags/config.rscrates/ignore/src/types.rs 等源码位置,理解每个行为背后的实现依据。

基础:逐行匹配与正则模式

ripgrep 是一个命令行搜索工具:它假定自己逐行读取文件,若某一行匹配你给定的模式就打印该行,不匹配则跳过。这是理解 ripgrep 一切输出格式(行号、文件分组、颜色高亮)的前提。

指南以搜索 ripgrep 自身源码为例。在 README.md 中查找字面词 fast

$ rg fast README.md
75:  faster than both. (N.B. It is not, strictly speaking, a "drop-in" replacement
88:  color and full Unicode support. Unlike GNU grep, `ripgrep` stays fast while
119:### Is it really faster than everything else?
124:Summarizing, `ripgrep` is fast because:
129:  optimizations to make searching very fast.

这里 fast 是一个"字面量"(literal)模式,ripgrep 对每一行做包含判断,并默认附上行号;若终端支持颜色,命中部分会被高亮。

ripgrep 同时支持完整的正则表达式。想找到"fast 后面还跟着若干字母"的行:

$ rg 'fast\w+' README.md
75:  faster than both. (N.B. It is not, strictly speaking, a "drop-in" replacement
119:### Is it really faster than everything else?

模式 fast\w+ 表示 fast 后跟一个或多个词字符(\w 匹配 aL 这类构词字符,不匹配 .、空格;+ 表示"前一模式重复一次或多次")。因此裸词 fast 不匹配,fasterfaste 都匹配。若改用 fast\w** 表示零次或多次),匹配到的行与 fast 相同,但颜色高亮范围会覆盖整个 faster 而不仅是 fast 前缀:

$ rg 'fast\w*' README.md
75:  faster than both. (N.B. It is not, strictly speaking, a "drop-in" replacement
88:  color and full Unicode support. Unlike GNU grep, `ripgrep` stays fast while
119:### Is it really faster than everything else?
124:Summarizing, `ripgrep` is fast because:
129:  optimizations to make searching very fast.

指南明确说明不提供完整的正则教程,ripgrep 所用的正则方言以 regex 文档为准(其 crate 位于 crates/regex/,正则配置入口见 crates/regex/src/config.rs)。

排查技巧:如果 ripgrep 提示"没有搜索任何文件",用 --debug 重新运行。指南指出的一个常见原因是 $HOME/.gitignore 中存在 * 规则——这与下文"自动过滤"机制直接相关。

递归搜索:ripgrep 的默认运行模式

指南第一个例子搜索单个文件,但 ripgrep 的默认模式是递归搜索当前工作目录,因此这几乎不需要额外参数。在解压后的 ripgrep 源码树中查找所有名为 write 的函数定义:

$ rg 'fn write\('
src/printer.rs
469:    fn write(&mut self, buf: &[u8]) {

termcolor/src/lib.rs
227:    fn write(&mut self, b: &[u8]) -> io::Result<usize> {
250:    fn write(&mut self, b: &[u8]) -> io::Result<usize> {
428:    fn write(&mut self, b: &[u8]) -> io::Result<usize> { self.wtr.write(b) }
...

要点:

  • 未给出路径时,rg foo 等价于 rg foo ./
  • ( 在正则中有特殊含义所以需要转义为 \(,也可以直接用 -F 把模式当字面量:rg -F 'fn write('
  • 结果按文件分组打印(先文件名后行),跨了 src 与依赖库 termcolor 两个目录;
  • 想限定范围,直接给出目录:rg 'fn write\(' src,或 cd 进目标目录后再搜索。

在当前仓库中,目录遍历逻辑位于 crates/ignore/src/walk.rs,它决定了哪些文件会进入搜索管线。

自动过滤:ripgrep 最关键的"不搜什么"

指南强调,递归搜索之后,ripgrep 最重要的特性是它默认不搜索什么。搜索目录时,默认忽略:

  1. 命中以下三类 glob 规则的文件与目录(按优先级从低到高):
    1. .gitignore 规则(包括全局与仓库级规则;也包括属于同一 git 仓库的父目录中的 .gitignore,除非给出 --no-require-git);
    2. .ignore 规则,与 gitignore 规则冲突时优先生效(同样包含父目录中的 .ignore);
    3. .rgignore 规则,与 .ignore 冲突时优先生效(同样包含父目录中的 .rgignore);
  2. 隐藏文件和目录;
  3. 二进制文件(ripgrep 把含 NUL 字节的文件视为二进制);
  4. 符号链接默认不跟随。

对应的开关:

行为 标志 短写
关闭全部忽略过滤 --no-ignore
搜索隐藏文件/目录 --hidden -.
把二进制当文本搜索 --text -a(注意:二进制可能向终端喷出控制字符)
跟随符号链接 --follow -L

指南还提供了一个递进式排障标志 --unrestricted-u):

  • -u:关闭 .gitignore 处理;
  • -uu:进而搜索隐藏文件与目录;
  • -uuu:进而搜索二进制文件。

当你不确定是过滤规则藏起了结果时,多加几个 -u 是最快的确认手段;仍无法解释时再用 --debug

gitignore 处理的完整范围:除了各级 .gitignore,ripgrep 还尊重仓库专属规则 $GIT_DIR/info/exclude,以及 core.excludesFile(在 Unix 类系统上通常是 $XDG_CONFIG_HOME/git/ignore)中的全局忽略规则。这些规则的收集逻辑见 crates/ignore/src/gitignore.rs

.ignore 覆写 .gitignore:假设某目录有如下 .gitignore

log/

log 目录不被 git 跟踪。但你可能希望搜索它的输出,又不想让它进 git。在同一目录创建 .ignore

!log/

由于 .ignore 优先级高于 .gitignore.rgignore 又高于 .ignore),ripgrep 会先看到白名单规则 !log/ 并搜索该目录。与 .gitignore 相同,.ignore 可以放在任意目录,规则相对于所在目录生效。

补充两个细节:

  • --ignore-file-case-insensitive.gitignore/.ignore 规则按大小写不敏感方式匹配,适合 Windows、macOS 这类大小写不敏感的文件系统;代价是明显的性能损耗,因此默认关闭;
  • glob 语义的权威解释参考 man gitignore

手动过滤一:glob 模式

自动过滤依赖环境(既有的 .gitignore),而 glob 过滤是临时的、显式的。仍以上述源码树为例,想看谁依赖参数解析器 lexopt

$ rg lexopt
[大量结果]

$ rg lexopt -g '*.toml'
Cargo.toml
57:lexopt = "0.3.0"

-g '*.toml' 的含义是"被搜索的每个文件都必须匹配这个 glob"。注意 '*.toml' 要用单引号,防止 shell 展开 *

glob 同样支持 ! 取反:

$ rg lexopt -g '!*.toml'
[大量结果,但都不以 .toml 结尾]

! 表示黑名单这一点"有点非标准",但作者有意与 .gitignore 的写法保持一致——只是语义方向相反:.gitignore! 前缀表示白名单,命令行上 ! 表示黑名单。

顺序即优先级:glob 的解释方式与 .gitignore 相同,后面的规则覆盖前面的:

$ rg lexopt -g '!*.toml' -g '*.toml'   # 只搜 *.toml

反过来:

$ rg lexopt -g '*.toml' -g '!*.toml'   # 什么都不匹配

因为只要存在至少一个非黑名单 glob,就要求每个被搜索文件至少匹配一个 glob;此时黑名单规则压过前面的 glob,导致任何文件都无法被搜索。

手动过滤二:文件类型

当你反复使用同一组 glob(比如总是只想看 Rust 文件),可以直接用文件类型替代 glob:

$ rg 'fn run' -g '*.rs'
# 等价于
$ rg 'fn run' --type rust
# 更简洁
$ rg 'fn run' -trust

--type 的本质是"给一组 glob 起一个名字",一个类型可以覆盖多种扩展名。以 C 语言为例,用 glob 需要写 -g '*.{c,h}',用类型只需 -tc

$ rg 'int main' -g '*.{c,h}'
$ rg 'int main' -tc

黑名单文件类型同理:

$ rg lexopt --type-not rust
$ rg lexopt -Trust     # -T = --type-not

-t 是"包含该类型",-T 是"排除该类型"。

查看某类型由哪些 glob 构成:

$ rg --type-list | rg '^make:'
make: *.mak, *.mk, GNUmakefile, Gnumakefile, Makefile, gnumakefile, makefile

内置类型覆盖常见的公开格式(定义集中在 crates/ignore/src/default_types.rs),你也可以自定义。例如把"web"文件定义为 HTML/CSS/JS:

$ rg --type-add 'web:*.html' --type-add 'web:*.css' --type-add 'web:*.js' -tweb title
# 或更简洁
$ rg --type-add 'web:*.{html,css,js}' -tweb title

再次 rg --type-add 'web:*.{html,css,js}' --type-list 时,web 会出现在列表中,尽管它不是内置类型。

重要--type-add 只对当前命令生效,不会被持久化。要全局可用,要么建 shell 别名:

alias rg="rg --type-add 'web:*.{html,css,js}'"

要么把 --type-add=web:*.{html,css,js} 写进 ripgrep 配置文件(见下文"配置文件"一节)。

从源码看,类型名还受到严格约束:crates/ignore/src/types.rsTypesBuilder::add 要求类型名只能是字母数字且不能占用 alladd_defL442-L479)还额外支持 {name}:include:{已有类型列表} 的复合定义形式,即一个类型可以由若干已有类型组合而成——这一点指南没有展开,属于源码层面的加分能力。

特殊的 all 类型

--type all 表示选择 --type-list 中列出的所有支持类型(包括命令行 --type-add 添加的)。等价于为每个内置类型各写一个 --type 标志。

指南给了一个很好的边界例子:当前目录有 my-shell-script(无扩展名脚本)和 my-shell-library.bash

  • rg --type shrg --type all 都只命中 my-shell-library.bash,因为 sh 类型的 glob 不匹配无扩展名文件;
  • 反过来 rg --type-not all 会搜索 my-shell-script 但不搜 my-shell-library.bash

源码中 all 的特殊处理见 crates/ignore/src/types.rs#L381-L404select/negate 遇到名字 all 时,会遍历当前已定义的全部类型逐个添加选择/反选择。

替换:--replace 只改输出,不改文件

ripgrep 提供有限的输出改写能力。仍以 rg fast README.md 为例,把命中片段替换为 FAST

$ rg fast README.md --replace FAST
75:  FASTer than both. (N.B. It is not, strictly speaking, a "drop-in" replacement
88:  color and full Unicode support. Unlike GNU grep, `ripgrep` stays FAST while
119:### Is it really FASTer than everything else?
124:Summarizing, `ripgrep` is FAST because:
129:  optimizations to make searching very FAST.

# 或简写
$ rg fast README.md -r FAST

--replace 只作用于匹配到的那部分文本。想替换整行,需要让模式覆盖整行:

$ rg '^.*fast.*$' README.md -r FAST
75:FAST
88:FAST
119:FAST
124:FAST
129:FAST

或者组合 --only-matching-o)与 --replace

$ rg fast README.md --only-matching --replace FAST
75:FAST
88:FAST
119:FAST
124:FAST
129:FAST

# 简写
$ rg fast README.md -or FAST

捕获组可以直接写进替换串。找 fast 后面跟的另一个词并连字符拼接:

$ rg 'fast\s+(\w+)' README.md -r 'fast-$1'
88:  color and full Unicode support. Unlike GNU grep, `ripgrep` stays fast-while
124:Summarizing, `ripgrep` is fast-because:

替换串 fast-$1 由字面 fast- 加第 1 号捕获组内容组成。捕获组从 0 开始编号,但第 0 组恒为整个匹配,第 1 组才是模式中第一个显式括号组。也可以用命名组,下面的命令与上例等价:

$ rg 'fast\s+(?P<word>\w+)' README.md -r 'fast-$word'
88:  color and full Unicode support. Unlike GNU grep, `ripgrep` stays fast-while
124:Summarizing, `ripgrep` is fast-because:

替换串中捕获组的展开实现位于 crates/matcher/src/interpolate.rs

必须牢记:ripgrep 从不修改你的文件,--replace 只控制输出,仓库中也没有任何"就地替换"标志。

配置文件:RIPGREP_CONFIG_PATH 与 rc 文件格式

默认参数并不总合适,而 shell 别名也不总是方便,因此 ripgrep 支持配置文件。它不会自动去任何目录找配置文件,必须显式设置环境变量:

export RIPGREP_CONFIG_PATH=$HOME/.ripgreprc

配置文件只有两条格式规则:

  1. 每行去掉首尾空白后作为一个 shell 参数;
  2. # 开头的行(前面可带任意空白)被忽略。

没有转义机制——每行按原样作为一个命令行参数交给 ripgrep。

一份示例配置(展示了格式的种种特性):

$ cat $HOME/.ripgreprc
# 不让 ripgrep 把超长行喷满终端,并显示预览
--max-columns=150
--max-columns-preview

# 添加我的 'web' 类型
--type-add
web:*.{html,css,js}*

# 默认搜索隐藏文件/目录
--hidden

# 用 glob 模式包含/排除文件或目录
--glob=!.git/*

# 或
--glob
!.git/*

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

# 大小写谁在乎!
--smart-case

带值的标志有两种等价写法:同一条 = 分隔(--max-columns=150),或标志与值分两行写。原因是 ripgrep 的参数解析器认识 --max-columns=150 这种"带值单参数",而写 --max-columns 150 两词时它无法确定关系。分两行完全等价,只是风格问题。注释鼓励常写,空行随意。

覆盖机制:假如你在用上面的配置,临时想看超过 150 列的长行,只需在命令行传 --max-columns 0(或 -M0)覆盖即可。原理是:配置文件参数被前插(prepended)到显式命令行参数之前,而后出现的标志覆盖先出现的标志,因此行为符合直觉。各标志的文档会说明它会被哪些标志覆盖。

两个实用收尾:

  • 不确定 ripgrep 正在读哪个配置文件时,加 --debug,调试输出会标注加载的配置及其读到的参数;
  • 想绝对确认没有读取任何环境配置,传 --no-config,无论未来 ripgrep 增加多少种配置方式,它都保证只信命令行。

源码印证:crates/core/flags/config.rsargs() 首先读取 RIPGREP_CONFIG_PATH,未设置时直接返回空参数并记录调试日志;parse_readerL84-L108)逐行 trim 后跳过空行与 # 行,每行转为 OsString 原样保留——这正对应文档描述的"无转义、每行一个参数"。文件内的单元测试还验证了 Unix 下可容忍非 UTF-8 字节、而 Windows 下会按行报错的平台差异。

文件编码:--encoding auto 的默认行为

编码本身是复杂话题,指南将其对 ripgrep 的要点归纳为:

  • 文件只是一堆字节,无法可靠地判断其编码;
  • 要么模式与文件编码一致,要么必须对模式或文件做转码;
  • ripgrep 在纯文本上表现最好,最常见的编码是 ASCII、latin1、UTF-8;特例是 Windows 环境中普遍存在的 UTF-16。

默认即 --encoding auto,其行为:

  • 假设所有输入 ASCII 兼容(凡是落在 ASCII 码点范围内的字节,其值就是该 ASCII 码点),这覆盖 ASCII、latin1、UTF-8;
  • ripgrep 对 UTF-8 支持最好:正则引擎支持 Unicode 特性,\w 按 Unicode 定义匹配所有词字符,. 匹配任意 Unicode 码点而非任意字节。这些构造都假定 UTF-8——遇到文件里的非 UTF-8 字节时,它们根本不会匹配;
  • 对 UTF-16,ripgrep 默认做"BOM 嗅探":读取文件前三字节,若是 UTF-16 BOM,则把文件内容从 UTF-16 转码为 UTF-8 再搜索(转码带来额外性能开销);遇到无效 UTF-16 时用 Unicode 替换码点顶替无效码元;
  • 其他编码用 -E/--encoding 指定(取值来自 Encoding Standard),ripgrep 假定所有被搜索文件(除非文件自带 BOM)都是该编码,并执行与 UTF-16 情况相同的转码步骤。

默认情况下 ripgrep 不要求输入是合法 UTF-8,它可以直接搜索任意字节。搜索非 UTF-8 内容时模式的有效性会下降;若文件字节不 ASCII 兼容,模式很可能什么都找不到。但这一模式很重要——它让你在"大体是二进制/乱码"的文件中找出其中的 ASCII 或 UTF-8 片段。

-E none 是特殊值:完全禁用一切编码逻辑(包括 BOM 嗅探),直接搜索文件原始字节、零转码。例如搜索字符串 Шерлок 的原始 UTF-16 编码:

$ rg '(?-u)\(\x045\x04@\x04;\x04>\x04:\x04' -E none -a some-utf16-file

当然,通常你不需要这么干,直接写原文即可:

$ rg 'Шерлок' some-utf16-file

最后在正则内部关闭 Unicode:若想让 . 匹配任意字节而非任意 Unicode 码点(比如搜二进制文件时,因为默认的 . 不匹配无效 UTF-8):

$ rg '(?-u:.)'

该开关作用于模式任意部分。下面这个例子找"一个 Unicode 词字符 + 一个 ASCII 词字符 + 一个 Unicode 词字符":

$ rg '\w(?-u:\w)\w'

二进制数据:三种模式的 NUL 启发式

除了隐藏文件与 .gitignore 规则,ripgrep 还默认跳过二进制文件——PDF、图片之类通常不是正则搜索目标,而且命中二进制内容时把二进制数据喷进终端可能引发各种怪事。

与"跳过隐藏文件"不同,二进制没有可靠判定法。权衡正确性与性能后,ripgrep 采用最简单有效的启发式:文件中只要含一个 NUL 字节就判定为二进制。麻烦在于大多数二进制文件只是"开头附近"就有 NUL,并非必然——NUL 也可能是大文件的最后一个字节,该文件仍算二进制。这给实现带来复杂度,也造成一些反直觉的用户体验。

宏观上 ripgrep 对二进制文件有三种模式:

  1. 默认模式:尽量把二进制文件从搜索中彻底移除,模仿自动过滤的语义——一旦发现是二进制就停止搜索。若在此之前已经打印过命中(因为 NUL 出现得很晚),会打印一条"搜索提前终止"的警告。该模式只作用于目录递归遍历发现的文件:显式给出的路径不受此约束,例如 rg foo .file 会搜隐藏的 .filerg foo binary-file 也会自动以"二进制模式"搜索 binary-file
  2. 二进制模式--binary 强制开启):与默认模式相似,但看到 NUL 后不总是立即停。它会继续搜到满足以下二者之一为止:文件末尾,或发现了一个匹配。因此该模式下"报告无匹配"意味着文件里确实没有匹配;命中时会打印类似默认模式的"提前终止"提示。目的是既能发现所有文件中的匹配,又不让二进制数据倒进终端。
  3. 文本模式-a/--text):彻底禁用二进制检测,所有文件都当文本搜。适合"大体是文本但含 NUL"的文件,或你就是想搜二进制数据。注意对超大二进制文件使用此模式时,ripgrep 可能占用大量内存。

还有一层实现细节会影响判定结果——检测范围取决于搜索策略

  • 使用内存映射(mmap)时,只在文件开头若干 KB 及每个命中行上做二进制检测;
  • 不使用 mmap 时,对所有被搜索字节做检测。

也就是说,同一文件是否被判为二进制可能因内部策略不同而变化。想保持判定一致,可用 --no-mmap 关闭内存映射(代价是在某些平台上搜索超大文件时轻微变慢)。

源码层面,检测策略枚举在 crates/searcher/src/line_buffer.rsBinaryDetectionNone/Quit(byte)/Convert(byte) 三态),crates/core/search.rs 中每次搜索前都会按配置 set_binary_detection,随后在 search_reader/search_path 中执行。

预处理器:--pre 让 ripgrep 会搜任何可转成文本的格式

在 ripgrep 中,预处理器(preprocessor)是一个外部命令,ripgrep 在搜索每个文件之前先用它转换输入。这让 ripgrep 无需"学会"某种格式,就能搜索任何能被自动转成文本的内容。

典型例子是搜 PDF。PDF 是二进制格式,页面上的文字未必是连续 UTF-8,所以即使加 -a/--text 也搜不到:

$ rg 'The Commentz-Walter algorithm' 1995-watson.pdf
$

可以先手动转文本再搜:

$ pdftotext 1995-watson.pdf > 1995-watson.txt
$ rg 'The Commentz-Walter algorithm' 1995-watson.txt
316:The Commentz-Walter algorithms : : : : : : : : : : : : : : :
7165:4.4 The Commentz-Walter algorithms
10062:in input string S , we obtain the Boyer-Moore algorithm. The Commentz-Walter algorithm
...

pdftotext 属于 poppler 库。)但目录里全是 PDF 时手动转换太痛苦,这时用 --pre--pre 接收一个命令名,对每个被搜索文件执行它:ripgrep 把文件路径作为唯一参数传给命令,同时把文件内容送入 stdin。据此写一个包装脚本:

$ cat preprocess
#!/bin/sh

exec pdftotext - -

preprocess1995-watson.pdf 放在同目录后即可:

$ rg --pre ./preprocess 'The Commentz-Walter algorithm' 1995-watson.pdf
316:The Commentz-Walter algorithms : : : : : : : : : : : : : : :
7165:4.4 The Commentz-Walter algorithms
10062:in input string S , we obtain the Boyer-Moore algorithm. The Commentz-Walter algorithm
...

注意 preprocess 必须能解析为 ripgrep 可读的命令:最简做法是放进 PATH(或等效机制)里,或使用绝对路径。指南还给出对比数据:同一 PDF 上,rg --pre ./preprocess ... -c 耗时 0.697 秒,而 pdfgrep ... -c 耗时 1.336 秒;如果批量搜 PDF,ripgrep 的并行能力会进一步放大差距。

源码印证这一接口契约:crates/core/search.rssearch_preprocessor 中,cmd.arg(path) 传入路径、stdin(Stdio::from(File::open(path)?)) 把文件内容送入 stdin,与文档描述完全一致;should_preprocessL284-L292)则说明:设置了预处理器但未给 glob 时,每个文件都会走预处理器。

更健壮的预处理器

上面的脚本对非 PDF 文件会失败:

$ echo foo > not-a-pdf
$ rg --pre ./preprocess 'The Commentz-Walter algorithm' not-a-pdf
not-a-pdf: preprocessor command failed: '"./preprocess" "not-a-pdf"':
-------------------------------------------------------------------------------
Syntax Warning: May not be a PDF file (continuing anyway)
Syntax Error: Couldn't find trailer dictionary
...

修复方法:只在"认为输入是非空 PDF"时才跑 pdftotext

#!/bin/sh

case "$1" in
*.pdf)
  # -s 保证文件非空
  if [ -s "$1" ]; then
    exec pdftotext - -
  else
    exec cat
  fi
  ;;
*)
  exec cat
  ;;
esac

还可以扩展到其他格式:文件名不能确定类型时,用 file 工具按内容嗅探:

#!/bin/sh

case "$1" in
*.pdf)
  if [ -s "$1" ]; then
    exec pdftotext - -
  else
    exec cat
  fi
  ;;
*)
  case $(file "$1") in
  *Zstandard*)
    exec pzstd -cdq
    ;;
  *)
    exec cat
    ;;
  esac
  ;;
esac

降低预处理器开销

每个文件都启动一次预处理器进程,开销不小。若只有少数文件需要预处理,可用 --pre-glob 限定只对匹配 glob 的路径启用:

$ time rg --pre pre-rg 'fn is_empty' -c
crates/globset/src/lib.rs:1
crates/matcher/src/lib.rs:2
crates/ignore/src/overrides.rs:1
crates/ignore/src/gitignore.rs:1
crates/ignore/src/types.rs:1

real    0.138

$ time rg --pre pre-rg --pre-glob '*.pdf' 'fn is_empty' -c
crates/globset/src/lib.rs:1
crates/ignore/src/types.rs:1
crates/ignore/src/gitignore.rs:1
crates/ignore/src/overrides.rs:1
crates/matcher/src/lib.rs:2

real    0.008

同样搜索 ripgrep 仓库,加 --pre-glob '*.pdf' 后从 0.138 秒降到 0.008 秒——因为几乎所有文件都不需要再启动预处理器子进程。--pre-glob 的匹配逻辑即前文源码中的 preprocessor_globsignore::overrides::Override)。

常用选项速查

ripgrep 的标志多到记不住,指南选取了日常使用频率最高的一组:

  • -h:简版帮助;
  • --help:完整版帮助(接近 man page 内容,建议管道进分页器);
  • -i/--ignore-case:忽略大小写,rg -i fast 同时匹配 fastfAStFAST
  • -S/--smart-case:类似 --ignore-case,但模式含大写字母时自动关闭忽略大小写。通常放进别名或配置文件;
  • -F/--fixed-strings:关闭正则,模式按字面量处理;
  • -w/--word-regexp:要求命中两侧都是词边界。相当于把模式包成 \b{start-half}(?:pattern)\b{end-half}。注意这些"半边界"不要求一侧是词字符:rg -w -e -2 能匹配 (-2) 中的 -2,而 rg '\b-2\b' 不能;
  • -c/--count:只报告命中行数总和;
  • --files:打印 ripgrep 将要 搜索的文件但不实际搜索——排查过滤问题的利器;
  • -a/--text:把二进制当纯文本搜索;
  • -U/--multiline:允许匹配跨多行;
  • -z/--search-zip:搜索压缩文件(gzip、bzip2、lzma、xz、lz4、brotli、zstd),默认关闭;
  • -C/--context:显示命中周围的上下文行;
  • --sort path:按文件名排序输出(会关闭并行,可能更慢);
  • -L/--follow:递归搜索时跟随符号链接;
  • -M/--max-columns:限制打印行长度;
  • --debug:打印调试输出,用于理解某个文件为何被忽略、以及 ripgrep 从环境加载了什么配置。

小结

ripgrep 的使用心法可以浓缩为三层:逐行正则匹配是基础(含 ?P<name> 命名组、(?-u:...) 按片段关闭 Unicode 等正则细节);过滤决定搜什么(.gitignore/.ignore/.rgignore 优先级链、-g glob、-t/-T 类型与特殊的 all);模式与接口处理特殊输入(--encoding/BOM 嗅探、NUL 三态二进制检测、--pre/--pre-glob 预处理器、--replace 只改输出)。遇到问题时,-u 阶梯与 --debug 是排障的第一选择,RIPGREP_CONFIG_PATH 配置文件 + --no-config 则是参数长期化管理的开关。以上每个行为在当前仓库中都能找到对应的实现位置:忽略规则收集在 crates/ignore/,二进制检测与搜索策略在 crates/searcher/,预处理器与压缩解包在 crates/core/search.rs,配置文件解析在 crates/core/flags/config.rs

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
982
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384