
pdfq:兼容 pdfgrep 的快速并行 PDF 搜索工具,用 Rust 重写
来源标题:Pdfq – Fast parallel PDF search, drop-in for pdfgrep (Rust)
开发者发布 pdfq,一个用 Rust 从零重写的 PDF 搜索工具,命令行与 pdfgrep 兼容,可作为其替代品。它用 pdf-extract 逐页提取文本,用 regex crate 匹配,并通过 rayon 多核并行搜索页面,支持 -i、-n、-c、-P、-r 等 pdfgrep 常用参数。输出格式、参数和 GNU-grep 风格退出码均沿用 pdfgrep,另提供可选的页面文本磁盘缓存。
以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
快速、并行的 PDF 搜索工具,命令行与 pdfgrep 兼容。
pdfq 是用 Rust 从零重写的实现。它使用 pdf-extract 逐页提取文本,用 regex crate(或在 -P 模式下用 fancy-regex)进行匹配,并通过 rayon 在所有核心上并行搜索页面。输出格式、命令行标志和退出码都遵循 pdfgrep,因此可以直接作为替代品使用。
兼容 pdfgrep 的标志:-i、-n、-c、-o、-l、-L、-q、-F、-P、-A/-B/-C、-m、-r、-R、--color、--page-range 等
- 并行的页面与文件处理(rayon)
- 现代正则引擎:默认使用 Rust regex,-P 模式使用 fancy-regex
- 可选的磁盘缓存,保存已提取的页面文本(--cache)
- GNU-grep 风格的退出码:0 表示匹配,1 表示无匹配,2 表示错误
- 彩色输出,遵循 GREP_COLORS(mt/ms/mc、fn、ln、se)
构建
cargo build --release
生成的二进制文件位于 target/release/pdfq。
pdfq [OPTION]... PATTERN FILE...
示例:
pdfq -n “error” report.pdf pdfq -r -i “todo” ./docs pdfq -c -e foo -e bar a.pdf b.pdf pdfq -n -C2 --page-range 3-5 “summary” thesis.pdf pdfq -l -F “exact string” .
运行 pdfq --help 查看完整选项列表。
| 代码 | 含义 |
|---|---|
| 0 | 至少有一处匹配 |
| 1 | 无匹配 |
| 2 | 错误(用法错误、文件无法读取等) |
使用 -q 时,匹配优先于错误:只要有任何匹配就立即以 0 退出。
递归遍历目录(-r)时的错误会输出到 stderr,但不会改变退出码,这一点与 pdfgrep 一致。
[filename<sep>][pagenum<sep>]text
sep 在匹配行上是 :,在上下文行上是 -。
- -n 打印页码(pdfgrep 没有行号,PDF 是按页的)
- -Z 将文件名分隔符替换为 NUL
- 上下文组之间用 -- 分隔,但仅在确实跳过了行时才输出
与 pdfgrep 的差异
- 文本提取使用 pdf-extract(纯 Rust)而非 poppler,因此在复杂 PDF 上版面重建可能略有不同
- 模式中的 . 不匹配换行(Rust regex 语义;POSIX 的 . 会匹配)。多行锚点:^ 只匹配页面文本的开头,$ 只匹配结尾
- 递归遍历的输出按名称排序以保证结果可复现;pdfgrep 按原始 readdir 顺序打印
- --help 由 clap 生成,列出所有选项,而非 pdfgrep 简短的“常用”列表
- 不支持 --unac 重音折叠(该选项会被拒绝并给出明确错误)
测试
单元测试和集成测试(包含针对加密 PDF 密码检查与 --cache 的回归测试套件):
cargo test
针对参考 pdfgrep 二进制文件的差分测试(比较 stdout、stderr 和退出码;程序名已归一化):
cargo build --release PDFGREP=/path/to/pdfgrep bash tests/difftest.sh
如果未设置 PDFGREP,脚本会使用 PATH 中的 pdfgrep,若找不到则以 2 退出。
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。