Como posso grep em arquivos PDF?

136

Existe uma maneira de pesquisar arquivos PDF usando o poder do grep, sem converter primeiro o texto no Ubuntu?

Dervin Thunk
fonte
1
Eu acho que você precisa analisá-lo tu PDF2Text, a fim de obter alguns resultados utilizáveis de volta ...
Johan
1
Para as pessoas que chegam aqui por meio de pesquisa: se você deseja convertê-lo primeiro em arquivos de texto, consulte Como pesquisar o conteúdo de vários arquivos PDF?
Martin Thoma 02/01

Respostas:

135

Instale o pacote pdfgrepe use o comando:

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

——————

Maneira mais simples é

pdfgrep 'pattern' *.pdf
pdfgrep 'pattern' file.pdf 
enzotib
fonte
5
Isso funciona no mac osx (Mavericks) também. Instale-o usando o brew. Simples. Obrigado.
Mikiemorales
7
Por curiosidade, verifiquei a fonte do pdfgrep e ele usa o poppler para extrair as strings do pdf. Quase exatamente como a resposta do @ wag apenas na paginação, em vez de, presumivelmente, no documento inteiro.
Andrew Martin
4
pdfgreptambém tem uma bandeira recursiva. Assim, esta resposta talvez pudesse ser reduzido a: pdfgrep -R pattern /path/. Embora possa ser menos eficaz se passar por todos os arquivos, mesmo que não seja um PDF. E percebo que há problemas com caracteres internacionais como å, ä e ö.
Rovanion
1
Na verdade, a -nopção é um profissional para o pdfgrep, pois permite incluir o número da página na saída (pode ser útil para processamento adicional).
JepZ
4
Essa resposta seria mais fácil de usar se explicasse quais bits do comando devem ser copiados literalmente e quais são os espaços reservados. O que é pattern? O que é {}? O que há com o `+`? Eu não tenho idéia na primeira leitura ... então vou para a página de manual, suponho.
Mark Amery
56

Se você poppler-utilsinstalou (padrão no Ubuntu Desktop), você pode "convertê-lo" rapidamente e canalizá-lo para grep:

pdftotext my.pdf - | grep 'pattern'

Isso não criará um arquivo .txt.

abanar
fonte
1
então .. você extrai o texto antes de cumprimentá-lo, o que significa que a resposta é "não".
akira
18
@akira O OP provavelmente significava "sem abrir o PDF em um visualizador e exportar para o texto"
Michael Mrozek
5
@akira Onde você vê "grep only"?
Michael Mrozek
6
@akira Bem, eu já disse o que acho que ele provavelmente quis dizer; ele não deseja exportar para texto antes de processá-lo. Duvido muito que ele tenha um problema com qualquer comando que converta em texto de qualquer forma; não há razão para não
fazê-lo
2
@sherrellbc O segundo argumento de pdftotexté o nome do arquivo no qual ele deve gravar. No entanto, por convenção, as ferramentas normalmente permitem gravar em stdoutvez de em um arquivo, especificando um -. Da mesma forma, algumas ferramentas gravariam stdoutpor padrão se você omitir completamente esse argumento (mas isso nem sempre é possível sem criar ambiguidade).
Joost
12

O pdfgrep foi escrito exatamente para esse fim e está disponível no Ubuntu.

Ele tenta ser principalmente compatível grepe, portanto, fornece "o poder do grep", especializado apenas em PDFs. Isso inclui opções comuns de grep, como --recursive, --ignore-caseou --color.

Em contraste com pdftotext | grep, o pdfgrep pode gerar o número da página de uma correspondência de maneira eficiente e geralmente é mais rápido quando não é necessário pesquisar o documento inteiro (por exemplo, --max-countou --quiet).

O uso básico é:

pdfgrep PATTERN FILE..

onde PATTERNestá a string de pesquisa e FILEuma lista de nomes de arquivos (ou curingas em um shell).

Veja a página de manual para mais informações.

hpdeifel
fonte
7

Não.

Um pdf consiste em pedaços de dados, alguns com texto, alguns com fotos e outros com XYZ sofisticado e mágico (por exemplo, arquivos .u3d). Esses pedaços são na maioria das vezes compactados (por exemplo, flat, consulte http://www.verypdf.com/pdfinfoeditor/compression.htm ). Para 'grep' um arquivo .pdf, você precisa reverter a compactação, também conhecida como extrair o texto.

Você pode fazer isso por arquivo com ferramentas como pdf2texte grep o resultado ou executar um 'indexador' (veja xapian.org ou lucene ) que cria um índice pesquisável a partir de seus arquivos .pdf e pode usar a pesquisa ferramentas de mecanismo desse indexador para obter o conteúdo do pdf.

Mas não, você não pode greparquivos pdf e espera por respostas confiáveis ​​sem extrair o texto primeiro.

akira
fonte
5
Considerando que pdfgrepexiste (veja acima), um "não" simples está incorreto.
Jonathan Cruz
6

Recoll pode pesquisar PDFs. Ele não suporta expressões regulares, mas possui muitas outras opções de pesquisa, portanto, pode atender às suas necessidades.

user39336
fonte
5

Você pode passar stringsprimeiro: -

cat file.pdf | strings | grep <...etc...>
Andy Smith
fonte
8
Basta usar strings file.pdf | grep <...>, você não precisacat
phunehehe
Sim - minha mente parece funcionar melhor com correntes ... :-)
Andy Smith
12
não funcionará se o texto estiver compactado, o que ocorre na maioria das vezes.
akira
6
Mesmo que o texto não seja compactado, geralmente são pequenos trechos de frases (nem mesmo palavras inteiras!) Finamente misturados com informações de formatação. Não é muito amigável para stringsou grep.
Jander
Você pode pensar em outra razão pela qual o uso de strings para isso não funcionaria? Descobri que o uso de strings funciona em alguns PDFs, mas não em outros.
hourback 24/11/2015
3

Dê uma olhada na ferramenta grep de recurso comum crgrep, que suporta a pesquisa em arquivos PDF.

Ele também permite pesquisar outros recursos, como conteúdo aninhado em arquivos, tabelas de banco de dados, metadados de imagens, dependências de arquivos POM e recursos da Web - e combinações desses, incluindo pesquisa recursiva.

Craig
fonte
2

tente isso

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

para imprimir as linhas, o padrão ocorre dentro do pdf

harish.venkat
fonte
2

CD para a sua pasta contendo o seu arquivo pdf e depois ..

pdfgrep 'pattern' your.pdf

ou se você deseja pesquisar em mais de um arquivo PDF (por exemplo, em todos os arquivos PDF da sua pasta)

pdfgrep 'pattern'  `ls *.pdf`

ou

pdfgrep 'pattern' $(ls *.pdf)
Rasmuss Rall
fonte
por que diabos você usa ls para colocar nomes de arquivos em parâmetros? Não é apenas mais lento, mas também é uma má ideia usar a lssaída como entrada para outros comandos . Apenas pdfgrep 'pattern' *.pdfé suficiente
phuclv
1

Há uma pergunta duplicada no StackOverflow. As pessoas sugerem uma variação de harish.venkarts:

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

A vantagem sobre a resposta semelhante aqui é a --with-filenamebandeira do grep. Isso também é um pouco superior ao pdfgrep, porque o grep padrão tem mais recursos.

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

user7610
fonte
Acho que seria melhor deixar isso como um comentário (ou editar) na resposta semelhante a que você está se referindo.
Bernhard
0

Aqui está um script rápido para pesquisar pdf no diretório atual:

#!/bin/bash

if [ $# -ne 1 ]; then
  echo "usage $0 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 "$0"' $1 \;
Nico
fonte
0

Presumo que você quer dizer tp não convertê-lo no disco, você pode convertê-los para stdoute depois cumprimentá-lo pdftotext. Grepping o pdf sem qualquer tipo de conversão não é uma abordagem prática, pois PDFé principalmente um formato binário.

No diretório:

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

ou no diretório e seus subdiretórios:

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

Também porque algumas pdfsão verificações, elas precisam ser OCR primeiro. Eu escrevi uma maneira bastante simples de pesquisar todos os PDFs que não podem ser grepeditados e ocrá-los.

Percebi que se um pdfarquivo não tem nenhuma fonte, geralmente não é pesquisável. Então, sabendo disso, podemos usar pdffonts.

As primeiras 2 linhas do pdffontssão o cabeçalho da tabela; portanto, quando um arquivo é pesquisável, tem mais de duas linhas de saída, sabendo disso, podemos criar:

gedit check_pdf_searchable.sh

depois cole

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

então torne-o executável

chmod +x check_pdf_searchable.sh

em seguida, liste todos os PDFs não pesquisáveis ​​no diretório:

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

ou no diretório e seus subdiretórios:

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

Se você deseja apenas pesquisar nomes / propriedades em pdf ... ou seqüências de caracteres simples que não são compactadas ou codificadas, em vez de stringsusar as opções abaixo

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

De 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

e cat --help:

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

O gpdf pode ser o que você precisa se estiver usando o Gnome! Verifique isso caso você não esteja usando o Gnome. Tem uma lista de visualizadores de PDF da CLI. Então você pode usar greppara encontrar algum padrão.

Dharmit
fonte