概述

ripgrep 是一个面向行的搜索工具,它在遵循 gitignore 规则的同时,递归地搜索当前目录以寻找正则表达式模式。ripgrep 在 Windows、MaCOS 和 Linux 上拥有一流的支持,可以下载并使用每个 release二进制文件。 ripgrep 类似于其他流行的搜索工具,如 ag,ACK 和 grep。

各大工具对比例子

此示例搜索整个 Linux 内核源树(运行make defconfig && make -j8后),找寻匹配项为[A-Z]+_SUSPEND,所有匹配必须是单词。在具有 Intel i7-6900K 3.2GHz 的系统上统计时间,并在启用 SIMD 的情况下编译 ripgrep。

请记住,单一的基准是不够的! 看到我博客上关于 ripgrep 的博文,其有更多的基准和分析进行了非常详细的比较.

工具 命令 行计数 时间
ripgrep(Unicode) rg -n -w '[A-Z]+_SUSPEND' 450 0.106s
git grep LC_ALL=C git grep -E -n -w '[A-Z]+_SUSPEND' 450 0.55
The Silver Searcher ag -w '[A-Z]+_SUSPEND' 450 0.895
git grep (Unicode) LC_ALL=en_US.UTF-8 git grep -E -n -w '[A-Z]+_SUSPEND' 450 2.266s
sift sift --git -n -w '[A-Z]+_SUSPEND' 450 3.505s
ack ack -w '[A-Z]+_SUSPEND' 一千八百七十八 6.823s
The Platinum Searcher pt -w -e '[A-Z]+_SUSPEND' 450 14.208s

(是的,ack 会有个bug)

这是另一个忽略 gitignore 文件和用白名单搜索的基准。语料库与前面的基准测试相同,传递给每个命令的相同标志,确保它们正在执行相同的工作:

工具 命令 行计数 时间
ripgrep rg -L -u -tc -n -w '[A-Z]+_SUSPEND' 404 0.079s
ucg ucg --type=cc -w '[A-Z]+_SUSPEND' 390 0.163s
GNU grep egrep -R -n --include='*.c' --include='*.h' -w '[A-Z]+_SUSPEND' 404 0.611s

(ucg 在存在符号链接时,行为略有不同)

最后,在一个单一的大文件(~9.3GB)上,ripgrep 和 GNU grep 之间的直接比较。OpenSubtitles2016.raw.en.gz:

工具 命令 线路计数 时间
ripgrep rg -w 'Sherlock [A-Z]\w+' 5268 2.108s
GNU grep LC_ALL=C egrep -w 'Sherlock [A-Z]\w+' 5268 7.014s

在上述基准中,传递-n标志(用于显示行号),会增加时间,2.640s的 ripgrep 和10.277s的 GNU grep.

安装

ripgrep 的二进制名是rg

安装以CentOS 7为例,新增yum源,/etc/yum.repo.d/copr.repo:

1
2
3
4
5
6
7
8
9
10
[copr:copr.fedorainfracloud.org:carlwgeorge:ripgrep]
name=Copr repo for ripgrep owned by carlwgeorge
baseurl=https://download.copr.fedorainfracloud.org/results/carlwgeorge/ripgrep/epel-7-$basearch/
type=rpm-md
skip_if_unavailable=True
gpgcheck=1
gpgkey=https://download.copr.fedorainfracloud.org/results/carlwgeorge/ripgrep/pubkey.gpg
repo_gpgcheck=0
enabled=1
enabled_metadata=1

安装

1
$ sudo yum install ripgrep -y

语法说明

1
2
3
4
5
6
USAGE:
rg [OPTIONS] PATTERN [PATH ...]
rg [OPTIONS] [-e PATTERN ...] [-f PATTERNFILE ...] [PATH ...]
rg [OPTIONS] --files [PATH ...]
rg [OPTIONS] --type-list
command | rg [OPTIONS] PATTERN

参数说明

参数 说明
-A, --after-context <NUM> 每次匹配后,显示 NUM 行。
-B, --before-context <NUM> 在每次匹配前,显示 NUM 行。
--block-buffered 强制,分块缓冲。
-b, --byte-offset 打印每个匹配行的,字节偏移量,从 0 开始。
-s, --case-sensitive 搜索,关注大小写(默认)。
--color <WHEN> 控制何时,使用颜色。
--colors <COLOR_SPEC>... 配置颜色设置和样式。
--column 显示列号。
-C, --context <NUM> 显示每场匹配前后的 NUM 行。
--context-separator <SEPARATOR> 设置,内容分隔符的字符串。
-c, --count 仅显示每个文件的匹配行数。
--count-matches 仅显示每个文件的单个匹配数。
--crlf 支持 CRLF 行终止符(在 Windows 上很有用)。
--debug 显示,调试消息。
--dfa-size-limit <NUM+SUFFIX?> regex DFA 的大小上限。
-E, --encoding <ENCODING> 指定要搜索的文件的文本编码。
-f, --file <PATTERNFILE>... 从给定的文件模式中,搜索。
--files 打印,要搜索的每个文件。
-l, --files-with-matches 只打印,至少有一个匹配的路径。
--files-without-match 只打印,包含零个匹配项的路径。
-F, --fixed-strings 将模式,视为字面字符串。
-L, --follow 遵循,符号链接。
-g, --glob <GLOB>... 包括或排除文件。
-h, --help 打印帮助信息。使用 --help 了解更多详细信息。
--heading 打印,按每个文件分组的匹配项。
--hidden 搜索隐藏的文件和目录。
--iglob <GLOB>... 不关心大小写,包括或排除的文件 glob 模式。
-i, --ignore-case 不区分大小写的搜索。
--ignore-file <PATH>... 指定,其他忽略文件。
-v, --invert-match 反匹配。
--json 以 JSON 行格式,显示搜索结果。
--line-buffered 强制,行缓冲。
-n, --line-number 显示行号。
-x, --line-regexp 仅显示由行边界包围的匹配项。
-M, --max-columns <NUM> 不要打印,超过此限制的行。
-m, --max-count <NUM> 限制匹配数。
--max-depth <NUM> 最多深入 NUM 个目录。
--max-filesize <NUM+SUFFIX?> 忽略,大于 NUM 的文件。
--mmap 尽可能,使用内存映射进行搜索。
-U, --multiline 启用,跨多行匹配。
--multiline-dotall 启用多行时,使”.”与新行匹配。
--no-config 从不读取配置文件。
--no-filename 不要用匹配的行,打印文件路径。
--no-heading 不要按每个文件,对匹配项进行分组。
--no-ignore 不遵循忽略文件。
--no-ignore-global 不遵循全局忽略文件。
--no-ignore-messages 禁止 gitignore 解析的错误消息。
--no-ignore-parent 不遵循忽略父目录中的文件。
--no-ignore-vcs 不要遵循 VCS 忽略文件。
-N, --no-line-number 没有行号。
--no-messages 禁止显示某些错误消息。
--no-mmap 不使用内存映射。
--no-pcre2-unicode 禁用 PCRE2 匹配的 Unicode 模式。
-0, --null 在文件路径后,打印 NUL 字节。
--null-data 使用 NUL 作为行终止符,而不是\n
--one-file-system 不要深入,到其他文件系统的目录中。
-o, --only-matching 打印仅匹配行的部分内容。
--passthru 打印匹配行和不匹配行。
--path-separator <SEPARATOR> 设置路径分隔符。
-P, --pcre2 启用 PCRE2 匹配。
--pre <COMMAND> 搜索每个文件的命令文件输出
--pre-glob <GLOB>... 从预处理命令中,包括或排除文件。
-p, --pretty --color always--heading--line-number的别名。
-q, --quiet 不要将任何内容,打印到 stdout。
--regex-size-limit <NUM+SUFFIX?> 已编译 regex 的大小上限。
-e, --regexp <PATTERN>... 要搜索的模式。
-r, --replace <REPLACEMENT_TEXT> 用给定的文本,替换匹配项。
-z, --search-zip 在压缩文件中搜索。
-S, --smart-case 智能案例搜索。(如果它包含大写字符,则将查询视为区分大小写,如果不包含,则不区分大小写。)
--sort <SORTBY> 按升序对结果排序。暗示 --threads=1
--sortr <SORTBY> 按降序对结果排序。暗示 --threads=1
--stats 打印有关此 ripgrep 搜索的统计信息。
-a, --text 像搜索文本一样,搜索二进制文件。
-j, --threads <NUM> 要使用的线程的近似数。
--trim 从匹配项中,删除前缀空格。
-t, --type <TYPE>... 仅搜索,与类型匹配的文件。
--type-add <TYPE_SPEC>... 为文件类型,添加新的 glob。
--type-clear <TYPE>... 清除文件类型的全局变量。
--type-list 显示所有支持的文件类型。
-T, --type-not <TYPE>... 不要搜索与类型匹配的文件。
-u, --unrestricted 降低”智能”搜索的级别。
-V, --version 打印版本信息
--vimgrep 以 Vim 兼容格式,显示结果。
-H, --with-filename 用匹配的行,打印文件路径。
-w, --word-regexp 只显示,由单词边界包围的匹配项。

测试

参考:https://github.com/chinanf-boy/ripgrep-zh/blob/master/GUIDE.zh.md

和grep使用方法差不多,统计Nginx访问日志的前十个ip:

1
rg -oN  "([0-9]{1,3}\.){3}[0-9]{1,3}" access.log-20200925 |sort -n|uniq -c|sort -rn|head -10

搜索单个文件

README.md,查找所有出现的fast单词:

1
rg fast README.md

在这个例子中,我们使用了模式fast\w+。此模式告诉 ripgrep 查找包含fast字母,其次是一个或多个字样字符的任何行。也就是说,\w匹配组成单词的字符(如aL,但不是.和``)这个+\w后意味着,”匹配以前的模式一次或多次”,这意味着fast这个词不会匹配,因为字符t后面没有字符。 但是一个faster可以匹配。faste也行。

1
rg 'fast\w+' README.md

递归搜索

例如,根路径搜索包含backup字段的文件,搜索非常快:

1
rg backup /*