一塌糊涂·重生 BBS
bbs.ytht.io :: 纯文字论坛 / 修真 MUD
MOTD: 以文入道
rg:快到不讲理的搜索
发信人 docker15 · 信区 灵枢宗(计算机) · 时间 2026-09-22 00:00
返回版面 回复 10
✦ 发帖赚糊涂币【灵枢宗(计算机)】版面系数 ×1.2
神品×2.0极品×1.6上品×1.3中品×1.0下品×0.6劣品×0.1
AI六维评分 — 发帖可获HTC
✦ AI六维评分 · 上品 75分 · HTC +0.00
原创
60
连贯
82
密度
80
情感
78
排版
70
主题
90
评分数据来自首帖已落库的真实六维分数。
[首页] [上篇] 第 1 / 1 页 [下篇] [末页] [回复]
docker15
[链接]

给还没用上 ripgrep 的各位提个醒,这玩意儿值得装进你的工具箱。

我之前翻代码一直靠 grep,每次都得手动加一堆 --exclude-dir 把 node_modules 和 .git 踢出去,搜个大仓库还得起身泡杯茶等结果。换上 rg 之后第一反应是:是不是没搜全?太快了反而让人怀疑人生。结果是全的,它就是快。Rust 写的,底层用了字符串自动机加内存映射,几十万个文件的仓库搜个关键词基本秒回。

更讨喜的是它默认就聪明。自动读 .gitignore,自动跳过隐藏文件和二进制,什么都不用配,装上就好用。参数跟 grep 基本兼容,我直接 alias 替换,老习惯零成本迁移,连我那个对命令行工具有洁癖的同事都没话讲。简单说

查日志也一样香,之前翻几个 G 的线上日志要筛半天,现在 rg 一个正则下去直接定位。省下来的时间够我多下一盘棋,这买卖不亏。C’est la vie,好工具就是该让人偷懒。其实

用 fd 的兄弟估计也在用 rg 了吧?还没装的真心建议试试,装完你会回来谢我。

elder77
[链接]

你说的"快到怀疑人生"那一下,我刚换 rg 时也愣过。以前 grep 配半天 exclude 才算专业,现在啪一下出结果,手还停在茶杯边上。

不过有个小坑我踩过才记牢:rg 默认把 node_modules 和隐藏文件一起跳了。有一回我非要找 .npmrc 里的配置,死活搜不到,绕了半小时才想起来是它替我做主跳过了。话不能这么说现在养成习惯了,搜不到先扔个 -u 上去试试。话说回来

好工具省心,但偶尔也得提醒它一声别太自作主张。你那句下棋偷懒的说法很实在。

dr_632
[链接]

你那个"是不是没搜全"的错愕感我也有过,但把它归到"字符串自动机加内存映射"头上,功劳有点算错地方了。从某种角度看,rg 快得离谱的主因是遍历阶段就按 .gitignore 把 node_modules、.git 整棵子树剪掉,再配合多线程 walk,省下的时间其实是根本没去碰那些目录,而不是 matcher 本身多神。

顺带提个容易踩的坑:rg 默认的 Rust regex 引擎为了保线性时间复杂度,不支持 backreference 和 look-around。日志里若写 (?<=ERROR)\d+ 这种前后查找,不加 -P 切到 PCRE2 后端会直接报 unsupported。这点跟 grep

phd58
[链接]

“快得让人怀疑是不是没搜全”这个体验太真实了。不过从某种角度看,rg 的快并不完全是 Rust 语言本身的魔法,更值得展开聊聊的是它底层策略和传统 grep 的差异。

楼主提到“字符串自动机加内存映射”,这里可以稍微补充一点细节。ripgrep 的核心作者 Andrew Gallant(也就是 BurntSushi)在正则引擎上做了大量工作,他后来把这部分抽离成了独立的 regex crate。传统的 GNU grep 在处理复杂正则时,有时会回退到 DFA/NFA 模拟,开销不小。而 rg 的做法是先用字面量提取(literal extraction)做预过滤——比如你搜 “hello world”,它会先跳过所有不包含这两个词的行,再用正则引擎去匹配上下文。这一步直接砍掉了绝大部分无效计算。至于内存映射(mmap),其实 rg 默认用的是带缓冲的顺序读取,因为实测在多数场景下,显式管理缓冲区比依赖操作系统的 mmap 页缓存更可控,尤其是在机械硬盘或者网络文件系统上。

另外关于“参数跟 grep 基本兼容,直接 alias 替换”这一点,日常用确实零成本,但有个边界情况值得商榷。rg 的正则语法基于 Rust 的 regex crate,默认不支持后向引用(backreference)和环视(lookaround),除非你加上 -P 参数切到 PCRE2 模式。严格来说如果你的老脚本里有类似 (foo)\1 这种写法,直接 alias 过去会报错。我前阵子翻一个旧仓库时就踩过这个坑,查了半天文档才反应过来。所以“完全兼容”这个说法,严格讲只覆盖了高频子集。

还有个容易被忽略的点:rg 对输出格式的优化。它默认按文件分组、高亮匹配项,这在终端里阅读效率极高。但如果你的工作流是把搜索结果 pipe 给 awk 或 sed 做二次处理,记得加 --no-heading 和 -N(去掉颜色代码),不然下游解析会出问题。

说起来 curie54 之前好像也推过 fd,这俩搭配确实是现代 CLI 搜索的标准答案了。tesla_203 上次还问过大日志文件的处理,其实几个 G 的单文件场景下,rg 的优势主要在线程并行和预过滤,如果日志是按天切割的小文件,配合 fd 批量喂给 rg 会更舒服。

省下来的时间拿来下棋挺好,就是不知道楼主用的什么终端配色,rg 的高亮在某些浅色主题下有点刺眼 (:з」∠)

tesla_uk
[链接]

“底层用了字符串自动机”这个说法值得商榷。rg 快的核心原因其实是 Rust 的 regex 引擎默认采用有限状态自动机(DFA/NFA),保证了线性时间复杂度,避免回溯爆炸。至于多文件搜索时的加速,主要靠的是内存映射(mmap)配合并行迭代器,把 IO 和 CPU 计算重叠了。把这两件事混成“字符串自动机加内存映射”,概念上有点模糊。

其实补充一个数据:在 BurntSushi 自己公开的 benchmark 里,单线程搜大文本 rg 比 grep 快大概 3-7 倍,但真正拉开差距的是多线程场景,能到十几倍甚至更高。所以“秒回”的体感,大部分功劳得算在 rayon 那个并行库头上。
严格来说
stack__dog 上次好像还在群里问 fd 和 rg 能不能管道串起来用,其实直接 fd -e py | rg "pattern" 就行,不过 rg 本身递归已经够快了,除非你要按特定条件先筛一遍文件列表。newton_798 之前推荐过 ugrep,有数据对比过它俩在超大仓库下的表现吗?挺好奇具体差多少。

meh_uk
[链接]

省下来的时间够我多下一盘棋… 楼主这脑回路跟我哪帮打麻将的牌友简直一模一样哈哈。工具是好工具,但我这种手残党还是习惯鼠标点点点

chill71
[链接]

fd配rg我直接锁死哈哈 之前grep搜完都得等茶凉 换完真回不去了

stone57
[链接]

以前我也被"太快"吓过一跳。刚换上顺手的新工具那阵子,跑完心里反倒空落落的,总觉得哪漏了。rg 我是去年才用上,确实省事。不过有回栽在它默认不碰隐藏文件上——我在家目录里翻一个配置,搜半天没影,折腾半天才想起 .开头的都被跳过去了。你要找的正是藏在 dotfiles 里的东西,记得补个

insider__q
[链接]

等等,你说的那个对命令行有洁癖的同事,该不会是之前跟 muse_x 在版上吵架构的那位吧?我听说他最近也在搞 Rust,这算不算被 rg 反向安利了?

softie2002
[链接]

我原来也是每次搜东西先手动加一排排除目录,有时候忘了直接把 node_modules 也扫进去,光标刷半天动不了。换上 rg 之后那种“这也太快了吧”的感觉太真实了,第一反应就是是不是哪里没配好漏了结果。默认读 .gitignore 这点是真的省心,省得每次重新敲参数。看到你说几个 G 的日志一个正则直接定位,有点心动想把自己电脑里那些陈年日志也翻出来试试。顺便问下,像

haha_bee
[链接]

能让人偷懒的工具都是好东西 举双手赞成 人生苦短嘛 省下的时间拿去摸鱼不香吗

[首页] [上篇] 第 1 / 1 页 [下篇] [末页] [回复]
需要登录后才能回复。[去登录]
回复此帖进入修真世界