¿Cómo puedo grep en archivos PDF?

136

¿Hay alguna manera de buscar archivos pdf usando el poder de grep, sin convertirlo primero a texto en Ubuntu?

Dervin Thunk
fuente
1
Creo que debe analizarlo en pdf2text para obtener algunos resultados utilizables ...
Johan
1
Para las personas que vienen aquí a través de la búsqueda: si está dispuesto a convertirlo primero en archivos de texto, eche un vistazo a ¿Cómo buscar el contenido de múltiples archivos pdf?
Martin Thoma

Respuestas:

135

Instale el paquete pdfgrep, luego use el comando:

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

——————

La forma más simple es

pdfgrep 'pattern' *.pdf
pdfgrep 'pattern' file.pdf 
enzotib
fuente
55
Esto también funciona en mac osx (Mavericks). Instálelo con brew. Sencillo. Gracias.
mikiemorales
77
Por curiosidad, verifiqué la fuente de pdfgrep y usa poppler para extraer cadenas del pdf. Casi exactamente como la respuesta de @ wag solo por página en lugar de, presumiblemente, todo el documento.
Andrew Martin
44
pdfgrepTambién tiene una bandera recursiva. Así que esta respuesta tal vez podría reducirse a: pdfgrep -R pattern /path/. Aunque podría ser menos efectivo si revisa todos los archivos, incluso si no es un PDF. Y noto que tiene problemas con caracteres internacionales como å, ä y ö.
Rovanion
1
En realidad, la -nopción es un profesional para pdfgrep, ya que permite incluir el número de página en la salida (puede ser útil para un procesamiento posterior).
JepZ
44
Esta respuesta sería más fácil de usar si explicara qué partes del comando deben copiarse literalmente y cuáles son marcadores de posición. ¿Qué es pattern? ¿Qué es {}? ¿Qué pasa con el '+'? No tengo idea desde la primera lectura ... así que supongo que voy a la página del manual.
Mark Amery
56

Si lo ha poppler-utilsinstalado (predeterminado en el escritorio de Ubuntu), puede "convertirlo" sobre la marcha y canalizarlo a grep:

pdftotext my.pdf - | grep 'pattern'

Esto no creará un archivo .txt.

meneo
fuente
1
entonces ... extrae el texto antes de seleccionarlo, lo que significa que la respuesta es "no".
akira
18
@akira El OP probablemente significó "sin abrir el PDF en un visor y exportar a texto"
Michael Mrozek
55
@akira ¿Dónde ves "grep only"?
Michael Mrozek
66
@akira Bueno, ya dije lo que creo que probablemente quiso decir; no quiere exportar a texto antes de procesarlo. Dudo mucho que tenga un problema con cualquier comando que se convierta a texto de alguna manera; no hay razón para no hacerlo
Michael Mrozek
2
@sherrellbc El segundo argumento de pdftotextes el nombre de archivo en el que debe escribir. Sin embargo, por convención, las herramientas generalmente le permiten escribir en stdoutlugar de en un archivo especificando un -lugar. Del mismo modo, algunas herramientas escribirían stdoutde forma predeterminada si omite dicho argumento por completo (pero esto no siempre es posible sin crear ambigüedad).
Joost
12

pdfgrep fue escrito exactamente para este propósito y está disponible en Ubuntu.

Intenta ser principalmente compatible grepy, por lo tanto, proporciona "el poder de grep", solo especializado para archivos PDF. Eso incluye opciones comunes de grep, como --recursive, --ignore-caseo --color.

En contraste con pdftotext | grep, pdfgrep puede generar el número de página de una coincidencia de manera eficiente y generalmente es más rápido cuando no tiene que buscar en todo el documento (por ejemplo, --max-counto --quiet).

El uso básico es:

pdfgrep PATTERN FILE..

donde PATTERNestá su cadena de búsqueda y FILEuna lista de nombres de archivo (o comodines en un shell).

Vea la página de manual para más información.

hpdeifel
fuente
7

No.

Un pdf consta de fragmentos de datos, algunos de ellos de texto, algunos de imágenes y algunos de ellos realmente mágicos XYZ (por ejemplo, archivos .u3d). Esos trozos se comprimen la mayoría de las veces (p. Ej. Plano, consulte http://www.verypdf.com/pdfinfoeditor/compression.htm ). Con el fin de 'grep' un .pdf que tiene para revertir la compresión también conocido como extraer el texto.

Puede hacerlo ya sea por archivo con herramientas tales como pdf2texty grep el resultado, o ejecutar un 'paso a paso' (mira xapian.org o Lucene ), que construye un índice de búsqueda de los archivos .pdf y luego se puede usar la búsqueda herramientas del motor de ese indexador para obtener el contenido del pdf.

Pero no, no puede greparchivos PDF y esperar respuestas confiables sin extraer primero el texto.

akira
fuente
55
Teniendo pdfgrepen cuenta que existe (ver arriba), un "no" plano es incorrecto.
Jonathan Cross
6

Recoll puede buscar archivos PDF. No admite expresiones regulares, pero tiene muchas otras opciones de búsqueda, por lo que puede satisfacer sus necesidades.

usuario39336
fuente
5

Puedes canalizarlo stringsprimero: -

cat file.pdf | strings | grep <...etc...>
Andy Smith
fuente
8
Simplemente use strings file.pdf | grep <...>, no necesitacat
phunehehe
Sí, mi mente parece funcionar mejor con las transmisiones ... :-)
Andy Smith
12
no funcionará si el texto está comprimido, que es la mayoría de las veces.
akira
66
Incluso si el texto no está comprimido, generalmente son pequeñas frases (¡ni siquiera necesariamente palabras completas!) Finamente entremezcladas con información de formato. No es muy amigable para stringso grep.
Jander
¿Puedes pensar en otra razón por la cual el uso de cadenas para esto no funcionaría? Descubrí que el uso de cadenas funciona en algunos archivos PDF pero no en otros.
regreso el
3

Eche un vistazo al recurso común grep tool crgrep que admite búsquedas dentro de archivos PDF.

También permite buscar otros recursos como contenido anidado en archivos, tablas de bases de datos, metadatos de imágenes, dependencias de archivos POM y recursos web, y combinaciones de estos, incluida la búsqueda recursiva.

Craig
fuente
2

prueba esto

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

para imprimir las líneas el patrón ocurre dentro del pdf

harish.venkat
fuente
2

cd a su carpeta que contiene su archivo pdf y luego ...

pdfgrep 'pattern' your.pdf

o si desea buscar en más de un solo archivo pdf (por ejemplo, en todos los archivos pdf de su carpeta)

pdfgrep 'pattern'  `ls *.pdf`

o

pdfgrep 'pattern' $(ls *.pdf)
Rasmuss Rall
fuente
¿Por qué demonios usas ls para poner nombres de archivo en los parámetros? No solo es más lento sino también una mala idea usar la lssalida como entrada para otros comandos . Solo pdfgrep 'pattern' *.pdfes suficiente
phuclv
1

Hay una pregunta duplicada en StackOverflow. La gente allí sugiere una variación de harish.venkarts responde:

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

La ventaja sobre la respuesta similar aquí es la --with-filenamebandera de grep. Esto es algo superior a pdfgrep también, porque el grep estándar tiene más características.

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

user7610
fuente
Creo que hubiera sido mejor dejar esto como un comentario (o edición) en la respuesta similar a la que te refieres.
Bernhard
0

Aquí hay una secuencia de comandos rápida para buscar pdf en el directorio actual:

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

Supongo que quiere decir que tp no lo convierte en el disco, puede convertirlos stdouty luego grep pdftotext. Agitar el pdf sin ningún tipo de conversión no es un enfoque práctico, ya que PDFes principalmente un formato binario.

En el directorio:

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

o en el directorio y sus subdirectorios:

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

Además, debido a que algunos pdfson escaneos, primero deben ser OCR. Escribí una forma bastante simple de buscar todos los archivos PDF que no se pueden grepeditar y OCR.

Noté que si un pdfarchivo no tiene ninguna fuente, generalmente no se puede buscar. Entonces, sabiendo esto, podemos usarlo pdffonts.

Las primeras 2 líneas pdffontsson el encabezado de la tabla, por lo que cuando se puede buscar un archivo tiene más de dos líneas de salida, sabiendo esto podemos crear:

gedit check_pdf_searchable.sh

luego pegue esto

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

luego hazlo ejecutable

chmod +x check_pdf_searchable.sh

luego enumere todos los archivos PDF que no se pueden buscar en el directorio:

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

o en el directorio y sus subdirectorios:

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

Si solo desea buscar nombres / propiedades de pdf ... o cadenas simples que no están comprimidas o codificadas, en lugar de hacerlo strings, puede usar el siguiente

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

y cat --help:

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

¡gpdf podría ser lo que necesitas si estás usando Gnome! Comprueba esto en caso de que no estés usando Gnome. Tiene una lista de lectores PDF de CLI. Entonces puedes usar greppara encontrar algún patrón.

Dharmit
fuente