有没有办法在位于特定驱动器上的多个 pdf 文件中搜索(grep/find)特定单词?

有没有办法在位于特定驱动器上的多个 pdf 文件中搜索(grep/find)特定单词?

我正在尝试查找保存在外部备份驱动器上的客户 pdf 文件,其中包含 8000 多个 pdf 文件和数百个文件夹。

例如,如果我想搜索驱动器 X: 上包含我的客户名称“Sequoia Group”的所有 pdf 文件,有哪些有用的命令行和/或工具来实现相关的输出结果?

我使用的是 MacOS High Sierra,带有 zsh,我还通过自制程序安装了 GNU grep、ack 和 pdfgrep。但是,我还没有找到该文件。

文件名未知,因为所有文件都保存为 PDF-Backup-0001、PDF-Backup-0002...等,

到目前为止,我使用了以下命令,但没有成功:

#grep -wirl "sequoia group" ./

#pdfgrep -iHncRZ "sequoia group"

#mdfind "sequoia group"

另外,建议使用此命令行,但是,我不确定在哪里放置名称,因此我将 /path 替换为驱动器的路径,并将模式替换为“sequoia”,仍然没有找到任何匹配项

#find /path -iname '*.pdf' -exec pdfgrep pattern {} + 
#find /Volumes/X Backup -iname '*.pdf' -exec pdfgrep "sequoia" {} + 

答案1

啊,这怎么这么熟悉啊……

在搜索目录的根目录中打开一个终端,然后

pdfgrep -ril  "sequoia group" >matches 2>bad.files

这将递归地-r搜索所有 pdf 文件中的搜索词,不区分大小写-i,并且仅返回文件名,而不返回匹配的文本-l

所有匹配的文件名都将写入名为 的文件matches,任何错误都将写入名为 的文件bad.files

matches可以将其复制到单独的目录以供参考。

while read f do; cp $f /wherever/I/want/$f; done < matches

它们bad.files要么已损坏,要么 OCR 不正确,因此您应该将它们复制到另一个目录,重新处理它们并再次搜索它们。

如果您急于使用,find因为您可能有等的变体pdfPDF那么

find /search/root/ -iname *.pdf -exec pdfgrep -il "sequoia group" {} ';' >matches 2>bad.files

您在上面要求对此进行解释...find我认为您得到的命令pdfgrep在上面进行了解释,重定向也是如此>

选项-exec获取命令find的输出find并将其放在您看到的位置{}

最后-exec你会看到我已经放了,;而你已经放了+

+导致-exec收集所有输出find并将其pdfgrep作为一长串参数传递给并运行 pdfgrep 一次。除非文件数量超过最大数量,否则工作正常。

;导致一次将-exec的输出提供find给一个文件。pdfgrep

后记。打开一些 pdf 文件,无论您用什么方式查看它们,并确保它们已经过 OCR 并且实际上是可搜索的。

如果不是,您可能需要从每个目录运行它

find /path/to/dir/ -maxdepth 1 -type f -iname "*.pdf" -print0 | while IFS= read -r -d $'\0' line; do pdfsandwich -lang eng "$line"; done

如果您可以让您的电脑专门处理所有 8,000 个文件,无论需要多长时间,那么只需删除-maxdepth 1并指向find您的搜索根目录即可。

答案2

首先,正如 @Motivated 在评论中询问的那样:PDF 是通过扫描纸质文档生成的还是通过某些程序(LibreOffice、Tex/LaTeX、MS Word 等)生成的?如果它们是扫描文档,那么这些方法将不是工作:您需要一个 OCR 程序将图像翻译成文本,然后您可以进行搜索。这可能是一个超出本答案范围的重大项目。在下文中,我假设这些 PDF 是由某些文字处理(或类似)程序生成的。特别是,pdfgrep假设可以有效地处理这些文件。

你需要两件事:

  • 一个程序,它将遍历目录层次结构,查找该层次结构中的所有匹配文件,并对找到的每个文件执行某些操作。就是这样find。例如,您可以说find /path/to/some/directory -type f -name 'PDF-Backup-*'并且find会找到所有常规文件(-type f),其名称以PDF-Backup- 任何地方在给定路径下/path/to/some/directory - 默认操作是打印找到的每个文件的路径名。

  • 一旦找到您感兴趣的所有文件,您需要一个程序来搜索每个文件中的给定字符串:pdfgrep将在这里工作(假设我们不属于上面讨论的扫描文件类别),但您想要给出它有一些选项:-i不区分大小写地搜索文件中的模式,因此pdfgrep -i sequia会找到sequoia, Sequioa,SEQUOIASeQuOiA,而不考虑大小写 - 这可能就是您想要的,除非您是真的确定它在文件中的拼写方式,并且与大小写无关的搜索会产生太多误报。您需要的另一个选项是-H:打印出找到匹配项的文件名[fn:1]。

现在您可以将两者结合起来:调用find来遍历层次结构,查找与条件匹配的所有文件,但不要让它对它使用默认操作(打印文件名)找到的每个文件进行操作,而是要求它执行不同的操作:在每个文件中搜索带有pdfgrep.您可以使用以下-exec选项来做到这一点find

find /path/to/some/directory -type f -name 'PDF-Backup-*' -exec pdfgrep -i -H sequoia '{}' \; 

语法有点晦涩:{}被调用中找到的每个文件替换pdfgrep,但由于大括号通常在 shell 中具有特殊含义,因此必须用引号引起来的大括号对。此外,;终止作为 参数的命令-exec,但它对 shell 也有特殊含义,并且必须用引号引起来 - 在本例中用单个反斜杠而不是两个引号,只是因为它更短。请确保完全按照所示内容输入这些内容。

[fn:1] 当搜索两个或多个文件时,文件名默认打印出来pdfgrep,但是当与上面最后一个项目符号结合pdfgrep使用时,会分别调用每个文件,因此默认情况下不打印文件名:这就是为什么是需要的。findpdfgrep-H

相关内容