Compruebe si los archivos PDF están dañados utilizando la línea de comandos en Linux

16

Tengo muchos archivos PDF en una carpeta.

¿Es posible verificar si uno o más archivos están dañados (cero páginas o descargas inacabadas) usando la línea de comando, sin necesidad de abrirlos uno por uno?

Kokizzu
fuente

Respuestas:

20

¿Quizás correr pdfinfo(aquí en Fedora en el poppler-utilspaquete) da una pista?

La mayor parte de la información en un archivo PDF está en el diccionario al final, por lo que si lo encuentra, debería estar bien. Haría algo como:

for f in *.pdf; do
  if pdfinfo "$f" > /dev/null; then
    : Nothing
  else
    echo "$f" is broken
  fi
done
vonbrand
fuente
66
Sugeriría reemplazar pdfinfo con pdftotext. De esta manera, se verificará todo el texto de cada página. Y el carácter> gt debería ser &> para que no aparezcan todos los mensajes de error.
schoetbi
Todos mis archivos PDF están marcados como rotos. Cientos de gigabytes de ellos. Incluyendo los que acabo de crear. Ya sea usando pdfinfoo pdftotext...
PatrickT
13

Este es mi guion

find . -iname '*.pdf' | while read -r f
  do
    if pdftotext "$f" &> /dev/null; then 
        echo "$f" was ok;   
    else
        mv "$f" "$f.broken";
        echo "$f" is broken;   
    fi; 
done
Schoetbi
fuente
Para aclarar: este script cambia el nombre de los archivos pdf que se diagnostican como "rotos" agregando .broken a la extensión .pdf.
PatrickT
5

Mi herramienta de elección para revisar archivos PDF es qpdf. qpdftiene un --checkargumento que hace bien en encontrar problemas en archivos PDF.

Verifique un solo PDF con qpdf:

qpdf --check test_file.pdf

Verifique todos los archivos PDF en un directorio con qpdf:

find ./directory_to_scan/ -type f -iname '*.pdf' \( -exec sh -c 'qpdf --check "{}" > /dev/null && echo "{}": OK' \; -o -exec echo "{}": FAILED \; \)

Explicación del comando:

  • find ./directory_to_scan/ -type f -iname '*.pdf' Buscar todos los archivos con la extensión '.pdf'

  • -exec sh -c 'qpdf --check "{}" > /dev/null && echo "{}": OK' \; Ejecute qpdfpara cada archivo encontrado y canalice todos los resultados a /dev/null. Imprima también el nombre del archivo seguido de ': OK' si el estado de retorno qpdfes 0 (es decir, sin errores)

  • -o -exec echo "{}": FAILED \; \) Esto se ejecuta si se encuentran errores: imprimir el nombre del archivo seguido de ": FAILED"


Dónde conseguirlo qpdf:

qpdftiene binarios de Linux y Windows disponibles en: https://github.com/qpdf/qpdf/releases . También puede usar su administrador de paquetes de elección para obtenerlo. Por ejemplo, en Ubuntu puedes instalar qpdf usando apt con el comando:

apt install qpdf
mugir
fuente
Sin embargo, qpdf --checkno detecta metadatos definidos de forma múltiple, que son incorrectos ya que son manejados de manera diferente por diferentes herramientas. He reportado un error . Otras herramientas como pdfinfoy pdftktampoco, pero no pretenden verificar la estructura del PDF.
vinc17
4

Me conseguí una respuesta:

for x in *.pdf; do echo "$x"; pdfinfo "$x" | grep Pages; done

Los PDF con errores mostrarán errores.

Kokizzu
fuente
44
Es una mala idea (y nunca realmente se necesita) iterar sobre la salida de ls: mywiki.wooledge.org/ParsingLs
slhck
2
@slhck: Esto debería manejarse con find (1). :-)
Restablecer Monica - M. Schröder
2

Todos los métodos que usan pdfinfoo pdftotextno me han funcionado. De hecho, me seguían dando falsos positivos y, a veces, creaban archivos que no necesitaba.

Lo que funcionó fue JHOVE .

Instalación:

Instale el jar desde el enlace anterior y actualice su variable de entorno PATH con este comando:

echo "export PATH=\$PATH:/REPLACE_WITH/YOUR/PATH_TO/jhove/" >> ~/.bash_profile

Actualice cada terminal con source ~/.bash_profiley estará listo para comenzar a usarlo en todo el sistema.

Uso Básico:

jhove -m pdf-hul someFile.pdf

Obtendrá mucha información sobre el pdf, más de lo que la mayoría de la gente probablemente necesita.

Bash One-Liner:
simplemente devuelve valido invalid:

if [[ $(jhove -m pdf-hul someFile.pdf | grep -a "Status:") == *"Well-Formed and valid"* ]]; then echo "valid"; else echo "invalid"; fi;

Tenga en cuenta que esto se ejecutó en Mac OS X, pero supongo que funciona igual con cualquier entorno Bash basado en Unix.

kraftydevil
fuente