如何在目录/子目录中搜索PDF文件的内容?我在找一些命令行工具。grep似乎不能搜索PDF文件。
grep
你需要一些工具,如pdf2text,首先将pdf转换为文本文件,然后在文本中搜索。(您可能会错过一些信息或符号)。
如果你正在使用一种编程语言,很可能有专门为此目的编写的pdf库。例如:Perl的http://search.cpan.org/dist/CAM-PDF/
你的发行版应该提供一个名为pdftotext的实用程序:
pdftotext
find /path -name '*.pdf' -exec sh -c 'pdftotext "{}" - | grep --with-filename --label="{}" --color "your pattern"' \;
"-"是将pdftotext输出到标准输出而不是文件的必要条件。 --with-filename和--label=选项将把文件名放在grep的输出中。 可选的--color标志很好,它告诉grep在终端上使用颜色输出
--with-filename
--label=
--color
(在Ubuntu中,pdftotext由包xpdf-utils或poppler-utils提供。)
xpdf-utils
poppler-utils
如果你想使用GNU grep中pdfgrep不支持的特性,这个使用pdftotext和grep的方法比pdfgrep更有优势。请注意: pdfgrep - 1.3。x支持-C选项打印上下文行。
pdfgrep
-C
试着在一个简单的脚本中使用'acroread',就像上面那样
有pdfgrep,它做的正是它的名字所暗示的。
pdfgrep -R 'a pattern to search recursively from path' /some/path
我用它做过简单的搜索,效果很好。
(Debian、Ubuntu和Fedora中都有软件包。)
自1.3.0版本起,pdfgrep支持递归搜索。这个版本从Ubuntu 12.10 (Quantal)开始在Ubuntu中可用。
这个具有破坏性的小脚本。祝你玩得开心。
function pdfsearch() { find . -iname '*.pdf' | while read filename do #echo -e "\033[34;1m// === PDF Document:\033[33;1m $filename\033[0m" pdftotext -q -enc ASCII7 "$filename" "$filename."; grep -s -H --color=always -i $1 "$filename." # remove it! rm -f "$filename." done }
我也遇到了同样的问题,因此我写了一个脚本,搜索指定文件夹中的所有pdf文件的字符串,并打印匹配查询字符串的pdf文件。
也许这对你有帮助。
你可以下载它在这里
如果你想使用pdftotext查看文件名,使用以下命令:
find . -name '*.pdf' -exec echo {} \; -exec pdftotext {} - \; | grep "pattern\|pdf"
Recoll是一个很棒的Unix/Linux全文GUI搜索应用程序,支持几十种不同的格式,包括PDF。它甚至可以将查询的确切页码和搜索词传递给文档查看器,从而允许您直接从它的GUI跳转到结果。
Recoll还提供了一个可行的命令行界面和浏览器界面。
有一个开源的公共资源grep工具crgrep,它可以在PDF文件中搜索,但也可以搜索其他资源,如档案中嵌套的内容、数据库表、图像元数据、POM文件依赖项和web资源——以及这些资源的组合,包括递归搜索。
Files选项卡下的完整描述几乎涵盖了该工具支持的内容。
我开发的crgrep是一个开源工具。
我的实际版本的pdfgrep(1.3.0)允许以下:
pdfgrep -HiR 'pattern' /path
当执行pdfgrep --help时:
pdfgrep --help
它在我的Ubuntu上运行得很好。
我喜欢@sjr的答案,但我更喜欢xargs vs -exec。我发现xargs更通用。例如,使用-P,我们可以在必要时利用多个cpu。
find . -name '*.pdf' | xargs -P 5 -I % pdftotext % - | grep --with-filename --label="{}" --color "pattern"
首先将所有pdf文件转换为文本文件:
for file in *.pdf;do pdftotext "$file"; done
然后像往常一样使用grep。这是特别好的,因为当您有多个查询和许多PDF文件时,它是快速的。
还有一个名为ripgrep-all的实用程序,它基于ripgrep。
它不仅可以处理PDF文档,比如Office文档和电影,而且作者索赔它比pdfgrep更快。
递归搜索当前目录的命令语法,第二个命令只限制PDF文件:
rga 'pattern' . rga --type pdf 'pattern' .
谢谢所有的好主意!
我尝试了xargs方法,但正如这里所指出的,xargs将使它不可能(或非常困难)包括打印实际的文件名……
所以我用GNU平行尝试了整个事情。
parallel "pdftotext -q {} - | grep --with-filename --label='['{}']' --color=always --context=5 'pattern'" ::: *.pdf
--context=5
-q
[]
{}
--label='{'{}'}'
'Example portable document file name with spaces.pdf'
'
--label={}
--color=always
--ignore-case
如果所有PDF文件都应该递归处理,包括当前目录(.)中的所有子目录,这可以通过find来完成:
.
find . -type f -iname '*.pdf' -print0 | parallel -0 "pdftotext -q {} - | grep --with-filename --label='['{}']' --color=always --context=5 'pattern'"
-iname '*.pdf'
-name '*.pdf'
-iname
-print
-print0
-0
作为处理整个命令行的一般建议,parallel --dry-run将打印将要执行的命令。
parallel --dry-run
$ find . -type f -iname '*.pdf' -print0 | parallel --dry-run -0 "pdftotext -q {} - | grep --with-filename --label='['{}']' --color=always --ignore-case --context=5 'pattern'" pdftotext -q ./test PDF file 1.pdf - | grep --with-filename --label='['./test PDF file 1.pdf']' --color=always --ignore-case --context=5 'pattern' pdftotext -q ./subdir1/test PDF file 2.pdf - | grep --with-filename --label='['./subdir1/test PDF file 2.pdf']' --color=always --ignore-case --context=5 'pattern' pdftotext -q ./subdir2/test PDF file 3.pdf - | grep --with-filename --label='['./subdir2/test PDF file 3.pdf']' --color=always --ignore-case --context=5 'pattern'
使用pdfgrep:
pdfgrep -HinR 'FWCOSP' DatenModel/
在这个命令中,我在文件夹DatenModel/中搜索单词FWCOSP。
DatenModel/
FWCOSP
正如你在输出中看到的,你可以有文件名和行号:
我使用的选项是:
-i : Ignores, case for matching -H : print the file name for each match -n : prefix each match with the number of the page where it is found -R : same as -r, but it also follows all symlinks.