我有一堆PDF文件,我的Perl程序需要对它们进行全文搜索,以返回包含特定字符串的文件。 到目前为止,我一直在使用它:
my @search_results = `grep -i -l \"$string\" *.pdf`;
其中$ string是要查找的文本。 然而,对于大多数pdf而言,这都失败了,因为文件格式显然不是ASCII。
我能做的最简单的事情是什么?
澄清: 有大约300个pdf的名字我事先不知道。 PDF :: Core可能有点矫枉过正。我试图让pdftotext和grep彼此玩得很好,因为我不知道pdf的名字,我找不到合适的语法。
使用Adam Bellaire建议的最终解决方案:
@search_results = `for i in \$( ls ); do pdftotext \$i - | grep --label="\$i" -i -l "$search_string"; done`;
答案 0 :(得分:9)
PerlMonks线程here讨论了这个问题。
对于您的情况,似乎最简单的方法是获取 pdftotext (命令行工具),然后您可以执行以下操作:
my @search_results = `pdftotext myfile.pdf - | grep -i -l \"$string\"`;
答案 1 :(得分:2)
我的第二个Adam Bellaire解决方案。我使用pdftotext实用程序来创建我的电子书库的全文索引。它有点慢,但它的工作。至于全文,请尝试PLucene或KinoSearch来存储全文索引。
答案 2 :(得分:2)
您可能需要查看PDF::Core。
答案 3 :(得分:2)
我的库CAM::PDF支持提取文本,但鉴于PDF语法的图形方向,这是一个固有的难题。因此,输出有时是胡言乱语。 CAM :: PDF捆绑了getpdftext.pl程序,或者您可以调用这样的功能:
my $doc = CAM::PDF->new($filename) || die "$CAM::PDF::errstr\n";
for my $pagenum (1 .. $doc->numPages()) {
my $text = $doc->getPageText($pagenum);
print $text;
}
答案 4 :(得分:1)
我使用的最简单的全文索引/搜索是mysql。您只需在表中插入适当的索引即可。你需要花一些时间计算字段的相对权重(标题中的匹配可能得分高于正文中的匹配),但这都是可能的,尽管有一些毛茸茸的SQL。
Plucene已被弃用(过去两年没有任何积极的工作)支持KinoSearch。 KinoSearch在一定程度上增长了对Plucene的架构限制的理解。
如果您有~300 pdf,那么一旦您从PDF中提取文本(假设PDF有文本而不仅仅是文本图像;)并且根据您的查询量,您可能会发现grep就足够了。
但是,我强烈建议使用mysql / kinosearch路由,因为它们已经涵盖了很多基础(词干,停用词,术语加权,令牌解析),而这些路线并没有因为陷入困境而受益。
KinoSearch可能比mysql路由更快,但是mysql路由为您提供了更广泛使用的标准软件/工具/开发人员体验。并且您可以使用sql的强大功能来处理您的自由文本搜索查询。
因此,除非您正在谈论巨大的数据集和疯狂的查询量,否则我的资金将用于mysql。
答案 5 :(得分:0)
您可以尝试使用Lucene(Perl端口称为Plucene)。搜索速度非常快,我知道PDFBox已经知道如何使用Lucene索引PDF文件。 PDFBox是Java,但在CPAN的某处可能存在非常类似的东西。即使你找不到已经将PDF文件添加到Lucene索引中的东西,也不应该自己做几行代码。 Lucene将为您提供更多搜索选项,而不仅仅是在文件中查找字符串。
还有一种非常快速和肮脏的方式。 PDF文件中的文本实际上存储为纯文本。如果您在文本编辑器中打开PDF或使用“字符串”,则可以在其中查看文本。二进制垃圾通常是嵌入的字体,图像等。