Ripgrep 是命令行下一个基于行的搜索工具,RipGrep 使用 Rust 开发,可以在多平台下运行,支持 Mac、Linux 和 Windows 等平台。RipGrep 与 The Silver Searcher、Ack 和 GNU Grep 的功能类似。
RipGrep 官方号称比其它类似工具在搜索速度上快上 N 倍,VSCode 也从 1.11 版本开始默认将 RipGrep 做为其搜索工具,由此其功能强大可见一斑。
项目地址:https://github.com/BurntSushi/ripgrep
Ripgrep 支持的一些特性
- 自动递归搜索 (grep 需要 -R)。
- 自动忽略 .gitignore 中的文件以及二进制文件和隐藏文件。
- 可以搜索指定文件类型,如:
rg -tpy foo
则限定只搜索 Python 文件,rg -Tjs foo
则排除掉 JS 文件。 - 支持大部分 Grep 的 特性,例如:显示搜索结果的上下文、支持多个模式搜索、高亮匹配的搜索结果以及支持 Unicode 等。
- 支持各种文本编码格式,如:UTF-8、UTF-16、latin-1、GBK、EUC-JP、Shift_JIS 等。
- 支持搜索常见格式的压缩文件,如:gzip、xz、lzma、bzip2、lz4 等。
- 自动高亮匹配的结果。
Ripgrep 官方性能基准测试结果
- 搜索整个 Linux 内核源代码
Tool | Command | Line count | Time |
---|---|---|---|
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.553s |
The Silver Searcher | ag -w '[A-Z]+_SUSPEND' |
450 | 0.589s |
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' |
1878 | 6.823s |
The Platinum Searcher | pt -w -e '[A-Z]+_SUSPEND' |
450 | 14.208s |
Tool | Command | Line count | Time |
---|---|---|---|
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 |
- 在单个大文件上对 Ripgrep 和 GNU Grep 进行比较,文件大小大约 9.3G。
Tool | Command | Line count | Time |
---|---|---|---|
ripgrep | rg -w 'Sherlock [A-Z]\w+' |
5268 | 2.108s |
GNU grep | LC_ALL=C egrep -w 'Sherlock [A-Z]\w+' |
5268 | 7.014s |
Ripgrep 效果图
安装 Ripgrep
Ripgrep 具有良好跨平台特性,支持在 Linux、macOS、Windows 等多种平台下安装。官方也提供了各平台对应的二进制版本,下面我们以 Linux 平台为例使用二进制版本进行安装。
1 | $ wget https://github.com/BurntSushi/ripgrep/releases/download/0.10.0/ripgrep-0.10.0-x86_64-unknown-linux-musl.tar.gz |
如果你使用其它平台,方法与其类似。你可根据实际情况在官方下载页面下载对应版本进行安装。当然官方也提供了其它多种多样的安装方式,具体可参考官方安装文档。
Ripgrep 语法格式
- 整体语法格式
1 | USAGE: |
- 支持的命令行选项
这里我们把一些常用选项做下介绍。
选项 | 说明 | 备注 |
---|---|---|
-A, --after-context <NUM> |
显示匹配内容后的 <NUM> 行。 |
会覆盖 --context 选项。 |
-B, --before-context <NUM> |
显示匹配内容前的 <NUM> 行。 |
会覆盖 --context 选项。 |
-b, --byte-offset | 显示匹配内容在文件中的字节偏移。 | 和 -o 一起使用时只打印偏移。 |
-s, --case-sensitive | 启用大小写敏感。 | 会覆盖 -i(--ignore case) 和 -S(--smart case) 选项。 |
–color <WHEN> |
什么时候使用颜色,默认值为:auto。可选值有:never、auto、always、ansi。 | 如果 --vimgre 选项被使用,那么默认值是 never。 |
–column | 显示匹配所在列数 (从 1 开始)。 | 如果不显示列号可用 --no-column 取消掉。 |
-C, --context <NUM> |
显示匹配内容的前面和后面的 <NUM> 行。 |
该选项会覆盖 -B 和 -A 选项。 |
–context-separator <SEPARATOR> |
在输出结果中分隔非连续的输出行 。 | 可以使用\x7F 或 \t ,默认是 -- 。 |
-c, --count | 只显示匹配结果的总行数。 | 如果只有一个文件给 Ripgrep,那么只打印匹配结果的总行数。可以用 --with-filename 来强制打印文件名,该选项会覆盖 --count-matches 选项。 |
–count-matches | 只显示匹配结果的总次数。 | 可以用 --with-filename 来强制在只有一个文件时也输出文件名。 |
–debug | 显示调试信息。 | |
–dfa-size-limit <NUM+SUFFIX?> |
指定正则表达式 DFA 的上限,默认为 10M。 | 该选项允许接受与 --max-filesize 相同大小的后缀标志。 |
-E, --encoding <ENCODING> |
指定文本编码格式, 默认是 auto。 | 更多编码格式参考:https://encoding.spec.whatwg.org/#concept-encoding-get |
-f, --file <PATTERNFILE> … |
从文件中读入搜索模式, 一行一个模式。 | 结合 -e/--regexp 参数可多个文件一起组合使用,所有组合会被匹配。 |
–files | 打印所有将被搜索的文件路径。 | 以 rg <options> --files [PATH...] 方式使用,不能增加搜索模式。 |
-l, --files-with-matches | 只打印有匹配的文件名。 | 该选项会覆盖 --files-without-match 。 |
–files-without-match | 只打印无匹配的文件名。 | 该选项会覆盖 --file-with-matches 。 |
-F, --fixed-strings | 把搜索模式当成常规文字而非正则表达式。 | 该选项可以用--no-fixed-strings 来禁止。 |
-L, --follow | 该选项会递归搜索符号链接,默认是关闭的。 | 该选项可以用 --no-follow 选项来手动关闭。 |
-g, --glob <GLOB> … |
包含或排除用于搜索匹配给定的文件和目录,可以用 ! 来取反。 | 该选项可以多次使用,会匹配 .gitignore 中的规则。 |
-h, --help | 打印帮助信息。 | |
–heading | 打印文件名到匹配内容的上方而不是在同一行。 | 该选项是默认启用的,可以用 --no-heading 来关闭。 |
–hidden | 启用搜索隐藏文件和文件夹。 | 默认情况下是忽略搜索隐藏文件和文件夹的, 可用 --no-hidden 来关闭。 |
–iglob <GLOB> … |
作用同 --glob , 但这个选项大小写不敏感。 |
|
-i, --ignore-case | 指定搜索模式中的大小写不敏感。 | 该选项会被 -s/--case-sensitive 或 -S/--smart-case 覆盖。 |
–ignore-file <PATH> … |
指定搜索时需忽略的路径,格式同 .gitignore , 可同时指定多个。 |
如果存在多个 --ignore-file 标记时,后面优先级会更高。 |
-v, --invert-match | 反向匹配,显示与给定模式不匹配的行。 | |
-n, --line-number | 显示匹配内容所在文件的行数,该选项默认是打开的。 | |
-x, --line-regexp | 只显示整行都匹配搜索模式的行。 | 该选项会覆盖 --word-regexp 。 |
-M, --max-columns <NUM> |
不打印长于 <NUM> 中指定节字大小的匹配行内容,只显示该行的匹配数。 |
|
-m, --max-count <NUM> |
限制一个文件中最多 <NUM> 行被匹配。 |
|
–max-depth <NUM> |
限制文件夹递归搜索深度。 | 如:rg --max-depth 0 dir/ 则表示不执行任何搜索。 |
–max-filesize <NUM+SUFFIX?> |
搜索时忽略大于 <NUM> byte 的文件。 |
SUFFIX 的单位可以是:K、M、G,默认是:byte。 |
–mmap | 尽量使用 Memory Maps 进行搜索,这样速度会更快。该选项是默认行为。 | 如果使用 --mmap 搜索文件时 Ripgrep 发生意外中止,可使用 --no-mmap 选项关闭它。 |
–no-config | 不读取 configuration 文件, 并忽略 RIPGREP_CONFIG_PATH 变量。 | |
–no-filename | 不要打印匹配文件的文件名。 | |
–no-heading | 不在每个匹配行上方打印文件名,而是在匹配行的同一行上打印。 | |
–no-ignore | 不读取忽略文件,如:.gitignore、.ignore 等。 | 该选项可以用 --ignore 关闭。 |
–no-ignore-global | 不读取全局的 ignore 文件,比如: $HOME/.config/git/ignore 。 |
该选项可以用 --ignore-global 关闭。 |
–no-ignore-messages | 取消解析 .ignroe、.gitignore 文件中相关错误信息。 | 该选项可通过 --ignore-messages 关闭。 |
–no-ignore-parent | 不读取父文件夹里的 .gitignore、.ignore 文件。 | 该选项可通过 --ignore-parent 关闭。 |
–no-ignore-vcs | 不读取版本控制器中的 .ignore 文件。 | 该选项可通过 --ignore-vcs 关闭。 |
-N, --no-line-number | 不打印匹配行数。 | |
–no-messages | 不打印打开和读取文件时相关错误信息。 | |
-0, --null | 在打印的文件路径后加一个 NUL 字符。 | 这对于结合 Xargs 使用时是非常有用的。 |
-o, --only-matching | 只打印匹配的内容,而不是整行。 | |
–passthru | 同时打印文件中匹配和不匹配的行。 | |
–path-separator <SEPARATOR> |
路径分隔符,在 Linux 上默认是 /,Windows 上默认是 \ 。 | |
–pre <COMMAND> |
用 <COMMAND> 处理文件后,并将结果传递给 Ripgrep。 |
该选项存在一定的性能损耗。 |
-p, --pretty | 该选项是 --color always --heading --line-number 的别名。 |
|
-q, --quiet | 该选项不会打印到标准输出, 如果匹配发现时就停止搜索。 | 当 RipGrep 用于 exit 代码时该选项非常有用。 |
–regex-size-limit <NUM+SUFFIX?> |
设置已编译正则表达式的上限,默认限制为10M。 | |
-e, --regexp <PATTERN> … |
使用正则来匹配搜索条件。 | 该选项可以多次使用,可打印匹配任何模式的行。 |
-r, --replace <REPLACEMENT_TEXT> |
用相应文件内容代替匹配内容打印出来。 | |
-z, --search-zip | 在 gz、bz2、xz、lzma、lz4 文件类型中搜索。 | 该选项可通过 --no-search-zip 关闭。 |
-S, --smart-case | 如果全小写,则大小写不敏感,否则大小写敏感。 | 该选项可通过 -s/--case-sensitive 和 -i/--ignore-case 来关闭。 |
–sort <SORTBY> |
将输出结果按升序进行排序,可排序类型有:path、modified、accessed、created 。 | |
–sortr <SORTBY> |
将输出结果按降序进行排序,可排序类型有:path、modified、accessed、created 。 | |
–stats | 打印出统计结果。 | |
-a, --text | 搜索二进制文件。 | 该选项可通过 --no-text 关闭。 |
-j, --threads <NUM> |
搜索时要使用的线程数。 | |
-t, --type <TYPE> … |
只搜索指定的文件类型。 | 可以通过 --type-list 来列出支持的文件类型。 |
–type-add <TYPE_SPEC> … |
添加一种文件类型。 | |
–type-clear <TYPE> … |
清除默认的文件类型。 | |
–type-list | 列出所有内置文件类型。 | |
-T, --type-not <TYPE> … |
不要搜索某种文件类型。 | |
-u, --unrestricted | -u 搜索.gitignore 里的文件, -uu 搜索隐藏文件,-uuu 搜索二进制文件。 |
|
-V, --version | 打印版本信息。 | |
–vimgrep | 每一次匹配都单独打印一行,如果一行有多次匹配会打印成多行。 | |
-H, --with-filename | 打印匹配的文件路径,该选项默认打开。 | 该选项可通过 --no-filename 关闭。 |
-w, --word-regexp | 把搜索参数作为单独单词匹配。 | 该选项会覆盖 --line-regexp 选项。 |
更多命令行选项,可通过 rg --help
自行查看。
Ripgrep 使用实例
搜索指定文件中包含关键字的内容
1 | $ rg 'github.com' README.md |
搜索指定文件中包含以关键字开头的单词的内容
1 | $ rg 'lang\w+' README.md |
搜索指定文件中包含以关键字开头的内容
1 | $ rg 'hexo\w*' README.md |
搜索指定目录及子目中包含关键字的内容
1 | $ rg 'github.com' ./ |
搜索以关键字为独立单词的内容
1 | $ rg -w 'github.com' ./ |
搜索包含关键字内容的文件并且只打印文件名
1 | $ rg -w 'github.com' ./ -l |
在指定文件类型格式为 JS 的文件中搜索包含关键字的内容
RipGrep 实现的方式存在多种多样,这里介绍比较常用的两种。
- 第一种:使用
--type
选项指定文件类型。
1 | $ rg 'function writeOnCanvas' --type js |
- 第二种:使用
--glob
选项来通配需要的文件类型。
1 | $ rg 'function writeOnCanvas' -g '*.js' |
如果要同时搜索多个文件类型可以写成下面这样。
1 | $ rg 'Hanzi' -g '*.{js,css}' |
在当前目下并且不包含文件类型格式为 CSS 的文件中搜索包含关键字的内容
1 | $ rg 'revertVowel' --type-not css |
你也可以用下面的更简洁的写法来达到同样的效果。
1 | $ rg 'revertVowel' -Tcss |
使用正则表达式进行关键字搜索
1 | $ rg -e "noConf.*lict" ./ |
搜索匹配关键字的内容及显示其上下内容各两行
1 | $ rg -e "noConf.*lict" -C2 |
搜索不包含关键字的内容
1 | $ rg -v "hexo" merge-configs.js |
搜索关键字并只显示关键字部分的内容
1 | $ rg -e "hexo.*warn" -o ./ |
搜索关键字并忽略关键字大小写的内容
1 | $ rg -ie "Return.*" merge.js |
把关键字当成常量字符进行搜索
关键字中包含 .(){}*+
类似字符时,不需要手动转义。
1 | $ rg -F "i++)" ./ |
如果要搜索的字符是以 -
开头时,要用 --
来作为分隔符。
1 | $ rg -- -1 merge.js |
或者使用 -e
参数也可以达到类似目的。
1 | $ rg -e "-1" source/js |
打印当前目下所有将被搜索的文件列表
1 | $ rg --files |
输出所有内置可识别文件类型
1 | $ rg --type-list |
自定义搜索文件类型
默认情况下,Ripgrep 附带了一堆预定义的类型。 通常,这些类型对应于众所周知的公共格式。 您也可以定义自己的类型,例如:您可能经常搜索 Web 类型文件,其中包含 Javascript、HTML 和 CSS 类型的文件。
1 | $ rg --type-add 'web:*.html' --type-add 'web:*.css' --type-add 'web:*.js' -tweb display |
也可以直接简写成
1 | $ rg --type-add 'web:*.{html,css,js}' -tweb display |
不过有一点是要注意的,上面增加的 Web 类型文件是临时的,只对当前命令有效。如果需要长期使用自定义的类型,你可以新增一个别名来在每次运行 RipGrep 时自动增加对应的文件类型。
1 | $ alias rg="rg --type-add 'web:*.{html,css,js}'" |
当然还有另一种方法来达到类似的目的,那就是使用 RipGrep 的配置文件,RipGrep 的配置文件默认为 $HOME/.ripgreprc
。
1 | $ cat $HOME/.ripgreprc |
将包含关键字的内容在查找结果中进行替换
RipGrep 提供了一个在查找过程中直接将关键字内容进行替换的功能,下面我们来看一个将关键字中部分内容的小写字母转大写字母的例子。
1 | $ rg browse README.md --replace Browse |
上面的结果实质上只是在标准输出中进行替换,并不会对实际文件进行修改。如果你需要对实际文件进行修改,你可以结合 Sed 命令来达到目的。
- 如果你使用 GNU Sed (CentOS、Ubuntu 等各种 Linux 发行版),可以使用以下命令。
1 | $ rg browse --files-with-matches | xargs sed -i 's/browse/Browse/g' |
- 如果您使用 BSD Sed( macOS 和 FreeBSD),则必须将以上命令修改为以下命令。
1 | $ rg browse --files-with-matches | xargs sed -i '' 's/browse/Browse/g' |
BSD Sed 中的 -i 标志需要提供文件扩展名以对所有已修改的文件进行备份,这里指定空字符串可防止进行文件备份。
- 如果您的文件路径中包含空格,则需要使用 NUL 终结符分隔文件路径。这里就需要使用
-0
参数来告诉 Ripgrep 在每个路径之间输出 NUL 字节,并告诉 Xargs 读取由 NUL 字节分隔的路径。
1 | $ rg Browse --files-with-matches -0 | xargs -0 sed -i '' 's/Browse/browse/g' |
直接在压缩文件中搜索包含关键字的内容
Ripgrep 目前仅支持 gzip、bzip2、lzma、lz4 和 xz 这几种压缩格式,并且需要在系统上已安装相应的 gzip,bzip2 和 xz 工具包。也就是说,Ripgrep 是通过 Shelling 到另一个进程来进行解压缩的。
1 | $ rg -z license UNLICENSE.gz |
Ripgrep 目前不会搜索存档格式,因此会跳过 *.tar.gz 文件。
自动补全功能
RipGrep 提供的二进制包中默认提供了 SHELL 自动补全功能,只需根据不同 SHELL 放到对应目录即可使用了。
- Bash
1 | $ mv rg.bash $XDG_CONFIG_HOME/bash_completion/ |
- ZSH
1 | $ mv _rg $fpath/ |
- Fish
1 | $ mv rg.fish $HOME/.config/fish/completions/ |
参考文档
http://www.google.com
http://t.cn/ROI5tMv
http://t.cn/Rs3caWW
http://t.cn/Rs3F6Ty