Comment puis-je grep dans les fichiers PDF?

136

Existe-t-il un moyen de rechercher des fichiers pdf en utilisant la puissance de grep, sans convertir au préalable en texte dans Ubuntu?

Dervin Thunk
la source
1
Je pense que vous avez besoin de l'analyser vous pdf2text pour obtenir des résultats exploitables ...
Johan
1
Pour les personnes venant ici via la recherche: Si vous souhaitez le convertir d'abord en fichier texte, consultez Comment rechercher le contenu de plusieurs fichiers PDF?
Martin Thoma

Réponses:

135

Installez le paquet pdfgrep, puis utilisez la commande:

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

——————

Le plus simple est

pdfgrep 'pattern' *.pdf
pdfgrep 'pattern' file.pdf 
enzotib
la source
5
Cela fonctionne aussi dans mac osx (Mavericks). Installez-le en utilisant une infusion. Facile. Merci.
mikiemorales
7
Par curiosité, j'ai vérifié la source de pdfgrep et il utilise poppler pour extraire les chaînes du fichier pdf. Presque exactement comme @ wag, la réponse ne concerne que le contenu d'une page à l'autre.
Andrew Martin
4
pdfgrepa également un drapeau récursif. Donc , cette réponse pourrait peut-être réduite à: pdfgrep -R pattern /path/. Bien que cela puisse être moins efficace s'il parcourt tous les fichiers, même s'il ne s'agit pas d'un PDF. Et je remarque qu’il a des problèmes avec les caractères internationaux tels que å, ä et ö.
Rovanion
1
En fait, l' -noption est un pro pour pdfgrep car elle permet d'inclure le numéro de page dans la sortie (peut être utile pour un traitement ultérieur).
JepZ
4
Cette réponse serait plus facile à utiliser si elle expliquait quels bits de la commande sont censés être copiés littéralement et lesquels sont des espaces réservés. C'est quoi pattern? C'est quoi {}? Qu'est-ce qui se passe avec le `+`? Je n'en ai aucune idée en première lecture ... donc je pars pour la page de manuel, je suppose.
Mark Amery
56

Si vous avez poppler-utilsinstallé (par défaut sur Ubuntu Desktop), vous pouvez le "convertir" à la volée et le rediriger vers grep:

pdftotext my.pdf - | grep 'pattern'

Cela ne créera pas de fichier .txt.

remuer
la source
1
alors .. vous extrayez le texte avant de le grep, ce qui signifie que la réponse est "non".
Akira
18
@akira Le PO voulait probablement dire "sans ouvrir le fichier PDF dans un visualiseur ni exporter au format texte"
Michael Mrozek
5
@akira Où voyez-vous "grep only"?
Michael Mrozek
6
@akira Eh bien, j'ai déjà dit ce que je pense qu'il voulait probablement dire; il ne veut pas exporter en texte avant de le traiter. Je doute fort qu'il ait un problème avec toute commande qui convertit en texte de quelque manière que ce soit; il n'y a aucune raison de ne pas
Michael Mrozek
2
@sherrellbc Le deuxième argument de pdftotextest le nom du fichier dans lequel il doit écrire. Cependant, par convention, les outils vous permettent généralement d’écrire au stdoutlieu de dans un fichier en spécifiant un -. De même, certains outils écrivent stdoutpar défaut si vous omettez complètement un tel argument (mais cela n’est pas toujours possible sans créer d’ambiguïté).
Joost
12

pdfgrep a été écrit exactement à cette fin et est disponible dans Ubuntu.

Il essaie d'être principalement compatible avec grepet fournit ainsi "la puissance de grep", spécialisé uniquement pour les PDF. Cela inclut les options communes de grep, telles que --recursive, --ignore-caseou --color.

À la différence de pdftotext | grep, pdfgrep peut afficher le numéro de page d'une correspondance de manière performante et est généralement plus rapide lorsqu'il n'est pas nécessaire de chercher dans tout le document (par exemple --max-countou --quiet).

L'utilisation de base est:

pdfgrep PATTERN FILE..

PATTERNest votre chaîne de recherche et FILEune liste de noms de fichiers (ou des caractères génériques dans un shell).

Voir la page de manuel pour plus d'infos.

hpdeifel
la source
7

Non.

Un fichier PDF est constitué de blocs de données, dont certains sous forme de texte, certaines d’images, et certains d’entre eux très magiques comme XYZ (par exemple, des fichiers .u3d). Ces morceaux sont la plupart du temps compressés (par exemple, à plat, consultez http://www.verypdf.com/pdfinfoeditor/compression.htm ). Afin de "grep" un .pdf, vous devez inverser la compression ou extraire le texte.

Vous pouvez le faire par fichier avec des outils tels que pdf2textet grep le résultat, ou vous exécutez un 'indexeur' (regardez xapian.org ou lucene ) qui construit un index interrogeable à partir de vos fichiers .pdf et vous pouvez ensuite utiliser la recherche. outils de moteur de cet indexeur pour obtenir le contenu du pdf.

Mais non, vous ne pouvez pas grepcréer de fichiers pdf et espérer des réponses fiables sans extraire le texte au préalable.

Akira
la source
5
Considérant qu'il pdfgrepexiste (voir ci-dessus), un "non" plat est incorrect.
Jonathan Cross
6

Recoll peut rechercher des PDF. Il ne prend pas en charge les expressions régulières, mais il possède de nombreuses autres options de recherche, il peut donc répondre à vos besoins.

utilisateur39336
la source
5

Vous pouvez le faire passer en stringspremier: -

cat file.pdf | strings | grep <...etc...>
Andy Smith
la source
8
Il suffit d'utiliser strings file.pdf | grep <...>, vous n'avez pas besoincat
phunehehe
Ouais - mon esprit semble mieux fonctionner avec les flux ... :-)
Andy Smith Le
12
ne fonctionnera pas si le texte est compressé, ce qui est le cas la plupart du temps.
Akira
6
Même si le texte n'est pas compressé, il s'agit généralement de petits morceaux de phrases (pas même de mots entiers!) Finement mélangés avec des informations de formatage. Pas très sympa pour stringsou grep.
Jander
Pouvez-vous penser à une autre raison pour laquelle l'utilisation de chaînes pour cela ne fonctionnerait pas? J'ai constaté que l'utilisation de chaînes de caractères fonctionne sur certains PDF mais pas sur d'autres.
heure de retour
3

Jetez un coup d'œil à l'outil de ressources communes grep crgrep, qui prend en charge la recherche dans les fichiers PDF.

Il permet également de rechercher d'autres ressources telles que du contenu imbriqué dans des archives, des tables de base de données, des métadonnées de l'image, des dépendances de fichiers POM et des ressources Web, ainsi que des combinaisons de celles-ci, notamment la recherche récursive.

Craig
la source
2

essaye ça

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

pour l'impression des lignes, le motif apparaît à l'intérieur du pdf

harish.venkat
la source
2

Allez dans votre dossier contenant votre fichier pdf et ensuite ..

pdfgrep 'pattern' your.pdf

ou si vous voulez chercher dans plus d'un fichier pdf (par exemple dans tous les fichiers pdf de votre dossier)

pdfgrep 'pattern'  `ls *.pdf`

ou

pdfgrep 'pattern' $(ls *.pdf)
Rasmuss Rall
la source
pourquoi diable utilisez-vous ls pour mettre les noms de fichiers dans les paramètres? Il est non seulement plus lent, mais aussi une mauvaise idée d’ utiliser la lssortie comme entrée pour d’autres commandes . Juste pdfgrep 'pattern' *.pdfest suffisant
phuclv
1

Il y a une question en double sur StackOverflow. Les gens là-bas suggèrent une variante de harish.venkarts répondent:

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

L'avantage sur la réponse similaire ici est le --with-filenamedrapeau pour grep. Ceci est également un peu supérieur à pdfgrep, car le grep standard a plus de fonctionnalités.

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

utilisateur7610
la source
Je pense qu'il aurait été préférable de laisser cela comme un commentaire (ou une modification) dans la réponse similaire à laquelle vous faites référence.
Bernhard
0

Voici un script rapide pour la recherche pdf dans le répertoire actuel:

#!/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
la source
0

Je suppose que vous voulez dire que vous ne voulez pas le convertir sur le disque, vous pouvez les convertir stdoutpuis le grep pdftotext. Grepping le pdf sans aucune sorte de conversion n'est pas une approche pratique puisqu'il PDFs'agit principalement d'un format binaire.

Dans le répertoire:

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

ou dans le répertoire et ses sous-répertoires:

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

De plus, comme certaines pdfnumérisations sont numérisées, elles doivent d'abord faire l'objet d'une reconnaissance optique. J'ai écrit un moyen assez simple de rechercher tous les fichiers PDF qui ne peuvent pas être édités grepet OCR.

J'ai remarqué que si un pdffichier n'a aucune police, il est généralement impossible de le rechercher. Donc, sachant cela, nous pouvons utiliser pdffonts.

L'en pdffonts-tête de la table est composé des deux premières lignes . Ainsi, lorsqu'un fichier est interrogeable, il produit une sortie de plus de deux lignes. Sachant cela, nous pouvons créer:

gedit check_pdf_searchable.sh

puis coller ceci

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

puis le rendre exécutable

chmod +x check_pdf_searchable.sh

puis répertoriez tous les fichiers PDF non interrogeables dans le répertoire:

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

ou dans le répertoire et ses sous-répertoires:

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

Si vous souhaitez simplement rechercher des noms / propriétés au format PDF ... ou des chaînes simples qui ne sont ni compressées ni codées, stringsvous pouvez utiliser la liste ci-dessous à la place de

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

et cat --help:

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

gpdf pourrait être ce dont vous avez besoin si vous utilisez Gnome! Cochez cette case si vous n'utilisez pas Gnome. Il contient une liste de lecteurs PDF CLI. Ensuite, vous pouvez utiliser greppour trouver un motif.

Dharmit
la source