有没有一种方法可以使用grep的功能搜索PDF文件,而无需在Ubuntu中先转换为文本?

评论

另请参见是否存在某种PDF到文本转换器?和命令行工具可搜索大量pdf文件中的短语。

对于来这里搜索的人:如果您愿意先将其转换为文本文件,请查看如何搜索多个pdf文件的内容?

#1 楼

安装软件包pdfgrep,然后使用以下命令:

find /path -iname '*.pdf' -exec pdfgrep pattern {} +


——————

最简单的方法:

pdfgrep 'pattern' *.pdf
pdfgrep 'pattern' file.pdf 


评论


这也适用于mac osx(Mavericks)。使用brew安装它。简单。谢谢。

–mikiemorales
2014年1月23日在1:28



出于好奇,我检查了pdfgrep的来源,并使用poppler从pdf中提取字符串。几乎完全与@wag的答案完全页面相关,而不是整个文档。

–安德鲁·马丁(Andrew Martin)
2014年9月16日上午11:11

pdfgrep也具有递归标志。因此,这个答案也许可以简化为:pdfgrep -R pattern / path /。即使它不是PDF,但如果遍历每个文件可能会不太有效。而且我注意到它与å,ä和ö等国际字符有关。

–万向
16年1月14日在12:11

实际上,-n选项是pdfgrep的专业版,因为它允许在输出中包括页码(可能有助于进一步处理)。

–JepZ
17年10月10日在20:18

如果它解释了命令的哪些位应按字面意义进行复制以及哪些是占位符,则此答案将更易于使用。什么模式?什么是 {}? +是怎么回事?初读时我不知道...所以我想去手册页。

– Mark Amery
18年4月20日在14:44

#2 楼

如果您安装了poppler-utils(在Ubuntu桌面上为默认设置),则可以即时对其进行“转换”并将其通过管道传输到grep

pdftotext my.pdf - | grep 'pattern'


这不会创建.txt文件。

评论


所以..在提取grep之前先提取文本,这意味着答案为“否”。

– akira
2011年1月31日15:18

@akira OP可能意味着“无需在查看器中打开PDF并导出为文本”

– Michael Mrozek
2011年1月31日17:36

@akira在哪里看到“仅grep”?

– Michael Mrozek
2011年1月31日18:55

@akira好吧,我已经说了我想他可能的意思;他不想在处理文本之前将其导出。我非常怀疑他的任何以任何方式转换为文本的命令都存在问题。没有理由不

– Michael Mrozek
2011年2月1日下午5:52

@sherrellbc pdftotext的第二个参数是应写入的文件名。但是,按照惯例,工具通常允许您通过指定-来写到stdout而不是文件。类似地,如果您完全省略这样的参数,则默认情况下,某些工具会写入stdout(但是,如果不产生歧义,这并非总是可能的)。

– Joost
16-09-23在14:06



#3 楼

pdfgrep正是为此目的而编写的,可在Ubuntu中使用。

它试图与grep大部分兼容,从而提供“ grep的强大功能”,仅适用于PDF。其中包括常见的grep选项,例如--recursive--ignore-case--color

pdftotext | grep相比,pdfgrep可以以高性能的方式输出匹配项的页码,并且通常在没有匹配项时更快搜索整个文档(例如--max-count--quiet)。

基本用法是:

pdfgrep PATTERN FILE..


其中PATTERN是您的搜索字符串,FILE文件名列表(或外壳中的通配符)。

有关更多信息,请参见手册页。

#4 楼

否。

pdf包含大量数据,其中一些是文本,其中一些是图片,其中一些确实非常奇特的XYZ(例如.u3d文件)。这些块大多数时候都是压缩的(例如,扁平,请访问http://www.verypdf.com/pdfinfoeditor/compression.htm)。为了“ grep” .pdf,您必须反转压缩方式,也就是提取文本。

您可以使用pdf2text之类的工具针对每个文件执行此操作,然后对结果进行grep,或者运行“索引器”(请查看xapian.org或lucene),它会从您的.pdf文件中构建可搜索的索引,然后您可以使用该索引器的搜索引擎工具获取pdf的内容。

但是,不,您不能grep pdf文件,并且希望在没有首先提取文本的情况下获得可靠的答案。

评论


考虑到pdfgrep的存在(请参见上文),“ no”是不正确的。

–乔纳森·克罗斯(Jonathan Cross)
18年8月28日在10:18

@JonathanCross考虑到以下问题:“使用grep的功能,而无需先转换为文本”,一个简单的“否”是正确的。

–Jivan Pal
20 Nov 24'8:58



#5 楼

Recoll可以搜索PDF。它不支持正则表达式,但是它还有许多其他搜索选项,因此它可能满足您的需求。

#6 楼

在StackOverflow上有一个重复的问题。那里的人建议使用harish.venkarts答案。

find /path -name '*.pdf' -exec sh -c 'pdftotext "{}" - | grep --with-filename --label="{}" --color "your pattern"' \;


与类似答案相比,这里的优点是grep的--with-filename标志。这也优于pdfgrep,因为标准grep具有更多功能。

https://stackoverflow.com/questions/4643438/how-to-search-contents-of-multiple-pdf -文件

评论


我认为最好将它留在您所指的类似答案中作为评论(或编辑)。

–伯恩哈德
2014年5月9日12:07

#7 楼

看一下通用资源grep工具crgrep,它支持在PDF文件中搜索。

它还可以搜索其他资源,例如嵌套在档案中的内容,数据库表,图像元数据,POM文件依赖项和Web。资源-以及这些资源的组合,包括递归搜索。

#8 楼

您可以先通过strings将其通过管道传输:-

cat file.pdf | strings | grep <...etc...>


评论


只需使用字符串file.pdf | grep <...>,您不需要猫

– phunehehe
2011年1月31日14:31

是的-我的想法似乎可以更好地与流... :-)

–安迪·史密斯(Andy Smith)
2011年1月31日14:57

如果文本被压缩,将无法正常工作,这在大多数情况下都是如此。

– akira
2011年1月31日15:18



即使文本未压缩,也通常是很小的句子(甚至不一定是整个单词!)与格式信息很好地混合在一起。对于字符串或grep不太友好。

–詹德
2011年1月31日下午16:08

您能想到另一个为什么不能使用字符串的原因吗?我发现使用字符串在某些PDF上有效,但在其他PDF上无效。

–小时制
15年11月24日在19:58

#9 楼

尝试使用

find /path -iname *.pdf -print0 | for i in `xargs 0`; do echo $i; \
    pdftotext "$i" - | grep pattern; done


打印线条,图案出现在pdf

#10 楼

这是在当前目录中搜索pdf的快速脚本:
#!/bin/bash

if [ $# -ne 1 ]; then
  echo "usage q4312078q VALUE" 1>&2
  exit 1
fi

echo 'SEARCH IS CASE SENSITIVE' 1>&2

find . -name '*.pdf' -exec /bin/bash -c 'pdftotext "{}" - | grep --with-filename --label="{}" --color "q4312078q"' "" \;


评论


由于篇幅太小,我无法编辑此内容:应该在find调用中加上$ 1的引号,否则它不适用于带有空格的搜索字词。

– ankon
20/08/25在11:44

@ankon修复它:)

–尼科
20/08/27在17:53

#11 楼

cd到包含pdf文件的文件夹中,然后..

pdfgrep 'pattern' your.pdf


,或者如果您要搜索多个pdf文件(例如,所有pdf-文件夹中的文件)

pdfgrep 'pattern'  `ls *.pdf`




pdfgrep 'pattern' $(ls *.pdf)


评论


为什么在地球上为什么使用ls将文件名放在参数中?使用ls输出作为其他命令的输入不仅速度较慢,而且不是一个好主意。只是pdfgrep'pattern'* .pdf就足够了

–phuclv
19年1月31日在5:07

@phuclv你错了。 pdfgrep'pattern'* .pdf将不起作用。

– f0nzie
20-2-25在19:55

@ f0nzie你错了。 $(ls * .pdf)将与* .pdf几乎完全相同,但更糟糕的是,因为特殊文件不受引号的保护

–phuclv
20-2-26在1:45

#12 楼

我假设您的意思是tp不会将其转换为磁盘,您可以将它们转换为stdout,然后使用pdftotext对其进行grep。由于PDF大多是二进制格式,因此不进行任何转换就无法获取pdf。

在目录中:

ls -1 ./*.pdf | xargs -L1 -I {} pdftotext {}  - | grep "keyword"


或在目录及其子目录中:

tree -fai . | grep -P ".pdf$" | xargs -L1 -I {} pdftotext {}  - | grep "keyword"


此外,由于某些pdf是扫描文件,因此它们必须首先是OCRed。我写了一种非常简单的方法来搜索所有无法通过grep进行操作的pdf文件并对其进行OCR。

我注意到,如果pdf文件没有任何字体,通常是无法搜索的。因此知道了这一点,我们就可以使用pdffonts了。

pdffonts的前两行是表头,因此当文件可搜索时,输出的行数超过两行,因此我们可以创建:

gedit check_pdf_searchable.sh


然后粘贴此

#!/bin/bash 
#set -vx
if ((`pdffonts "" | wc -l` < 3 )); then
echo 
pypdfocr ""
fi


然后使其可执行

chmod +x check_pdf_searchable.sh


然后在目录中列出所有不可搜索的pdf:

ls -1 ./*.pdf | xargs -L1 -I {} ./check_pdf_searchable.sh {}


或在目录及其子目录中:

tree -fai . | grep -P ".pdf$" | xargs -L1 -I {} ./check_pdf_searchable.sh {}


#13 楼

如果您只想搜索pdf名称/属性...或未经压缩或编码的简单字符串,则可以使用下面的

grep -a STRING file.pdf
cat -v file.pdf | grep STRING


来代替strings grep --help

      --binary-files=TYPE   assume that binary files are TYPE;
                            TYPE is 'binary', 'text', or 'without-match'
  -a, --text                equivalent to --binary-files=text


cat --help

  -v, --show-nonprinting   use ^ and M- notation, except for LFD and TAB


#14 楼

如果您使用的是Gnome,则可能需要gpdf!如果您不使用Gnome,请选中此复选框。它具有CLI pdf查看器列表。然后您可以使用grep查找一些模式。

#15 楼

 pdfgrep -r --include "*.pdf" -i 'pattern'
 


评论


欢迎来到该站点,并感谢您的贡献。您能否对这些选项的含义添加一些解释?这也可能有助于说明您的方法与该问题的其他答案(建议使用pdfgrep)有何不同。

– AdminBee
20年8月17日在9:53

#16 楼

最快的方法是

grep -rinw "pattern" --include \*.pdf *


评论


欢迎来到该网站。您介意为您提出的解决方案添加更多解释,以使非专家更容易访问吗?例如,您的grep命令行在不熟悉grep的人可能不知道的子目录中进行递归搜索。另外,您包括了-i标志,尽管忽略大小写可能并不总是用户想要的。另外,请说明您的方法与例如@phuclv等。

– AdminBee
20年1月21日在8:12



正如AdminBee所说,该问题并不要求区分大小写的搜索或递归目录搜索。 -n和-w选项也不是问题所在。但是,更重要的是,该答案告诉您如何搜索名称以.pdf结尾的文本文件-您错过了问题的重点。

– G-Man说“恢复莫妮卡”
20年1月21日在8:22

#17 楼

less mypdf.pdf | grep "Hello, World"