¿Diferencia de dos archivos pdf?

39

Estoy buscando un buen programa para mostrarme las diferencias entre dos archivos pdf similares. En particular, estoy buscando algo que no solo ejecute diff en una versión ASCII (con "pdftotext") de los archivos. Esto es lo que hace pdfdiff.py .

krumpelstiltskin
fuente
¿Tiene que ser de código abierto y gratuito?
Rinzwind
@Rinzwind: Eso sería preferible, por supuesto.
krumpelstiltskin
inetsoftware.de/other-products/pdf-content-comparer/… 2.2 aquí indica que se puede usar en Linux (runPDFC.sh) pero el archivo no está en el archivo (solo un murciélago ...) pero es java así que tal vez renombrándolo (?)
Rinzwind
@Rinzwind: no sé lo suficiente sobre Java para entender por qué no se está ejecutando. lo hago: java -cp. -jar PDFC.jar pero obtener un java.lang.NoClassDefFoundError :(
krumpelstiltskin
@Rinzwind: ejecuté esto en Windows; El programa es terrible. crea png que son ilegibles.
krumpelstiltskin

Respuestas:

28

Puede usar DiffPDF para esto. De la descripción:

DiffPDF se utiliza para comparar dos archivos PDF. Por defecto, la comparación es del texto en cada par de páginas, pero también se admite la comparación de la apariencia de las páginas (por ejemplo, si se cambia un diagrama o se reformatea un párrafo). También es posible c> comparar páginas particulares o rangos de páginas. Por ejemplo, si hay dos versiones de un archivo PDF, una con las páginas 1-12 y la otra con las páginas 1-13 debido a que se agregó una página adicional como página 4, se pueden comparar especificando dos rangos de páginas, 1 -12 para el primero y 1-3, 5-13 para el segundo. Esto hará que DiffPDF compare páginas en los pares (1, 1), (2, 2), (3, 3), (4, 5), (5, 6), y así sucesivamente, hasta (12, 13).

qbi
fuente
2
Esto es lo mejor que he visto. El único problema que veo es que compara los archivos PDF página por página. Entonces, si agrega un párrafo en say, página 1, el comienzo y el final de cada página después de eso no coinciden. :(
krumpelstiltskin
3
Creo que el enlace ya no es correcto. La nueva versión 3. * parece estar disponible solo para Windows. Sin sudo apt-get install diffpdfembargo, la versión anterior 2. * todavía se puede instalar a través de .
peq
22

Acabo de descubrir un truco para hacer que DiffPDF (el programa sugerido por @qbi) sea utilizable para más que cambios menores. Lo que hago es concatenar todas las páginas PDF en un rollo largo usando pdfjam y luego comparar los rollos. ¡Funciona incluso cuando se quitan o insertan secciones grandes!

Aquí hay un script bash que hace el trabajo:

#!/bin/bash
#
# Compare two PDF files.
# Dependencies:
#  - pdfinfo (xpdf)
#  - pdfjam  (texlive-extra-utils)
#  - diffpdf
#

MAX_HEIGHT=15840  #The maximum height of a page (in points), limited by pdfjam.

TMPFILE1=$(mktemp /tmp/XXXXXX.pdf)
TMPFILE2=$(mktemp /tmp/XXXXXX.pdf)

usage="usage: scrolldiff -h FILE1.pdf FILE2.pdf
  -h print this message

v0.0"

while getopts "h" OPTIONS ; do
    case ${OPTIONS} in
        h|-help) echo "${usage}"; exit;;
    esac
done
shift $(($OPTIND - 1))

if [ -z "$1" ] || [ -z "$2" ] || [ ! -f "$1" ] || [ ! -f "$2" ]
then
  echo "ERROR: input files do not exist."
  echo
  echo "$usage"
  exit
fi

    #Get the number of pages:
pages1=$( pdfinfo "$1" | grep 'Pages' - | awk '{print $2}' )
pages2=$( pdfinfo "$2" | grep 'Pages' - | awk '{print $2}' )
numpages=$pages2
if [[ $pages1 > $pages2 ]]
then
  numpages=$pages1
fi

     #Get the paper size:
width1=$( pdfinfo "$1" | grep 'Page size' | awk '{print $3}' )
height1=$( pdfinfo "$1" | grep 'Page size' | awk '{print $5}' )
width2=$( pdfinfo "$2" | grep 'Page size' | awk '{print $3}' )
height2=$( pdfinfo "$2" | grep 'Page size' | awk '{print $5}' )

if [ $(bc <<< "$width1 < $width2") -eq 1 ]
then
  width1=$width2
fi
if [ $(bc <<< "$height1 < $height2") -eq 1 ]
then
  height1=$height2
fi

height=$( echo "scale=2; $height1 * $numpages" | bc )
if [ $(bc <<< "$MAX_HEIGHT < $height") -eq 1 ]
then
  height=$MAX_HEIGHT
fi
papersize="${width1}pt,${height}pt"



    #Make the scrolls:
pdfj="pdfjam --nup 1x$numpages --papersize {${papersize}} --outfile"
$pdfj "$TMPFILE1" "$1"
$pdfj "$TMPFILE2" "$2"

diffpdf "$TMPFILE1" "$TMPFILE2"

rm -f $TMPFILE1 $TMPFILE2
krumpelstiltskin
fuente
2
Hice su script compatible con espacios en blanco y agregué archivos temporales únicos. Espero que no te moleste.
Glutanimate
2
También se corrigió un pequeño error en el que el script creaba un archivo de texto vacío en el directorio de trabajo. (recuerde usar siempre corchetes dobles con sentencias if que usan ">" y operandos relacionados.)
Glutanimate
2
Una última observación: este script funcionará bien solo para documentos de tamaño DIN A4. Tendrá que ajustar el valor PAGEHEIGHT para que funcione con documentos más pequeños. Estoy seguro de que hay una manera de automatizar esto, pero no sé cómo atm.
Glutanimate
2
Gracias por hacer las mejoras @Glutanimate. He agregado soporte para la comparación de archivos PDF de tamaños arbitrarios y diferentes (siempre y cuando las páginas dentro de cada archivo PDF sean de tamaño uniforme, es decir).
krumpelstiltskin
guardado en una esencia por conveniencia gist.github.com/timabell/9616807b2fe3fa60f234
Tim Abell el
8

Aunque esto no resuelve el problema directamente, aquí hay una buena manera de hacerlo todo desde la línea de comandos con pocas dependencias:

diff <(pdftotext -layout old.pdf /dev/stdout) <(pdftotext -layout new.pdf /dev/stdout)

https://linux.die.net/man/1/pdftotext

Funciona muy bien para las comparaciones básicas de pdf. Si tiene una versión más nueva de pdftotext, puede probar en -bboxlugar de -layout.

En cuanto a los diferentes programas, me gusta usar diffuse, por lo que el comando cambia muy ligeramente:

diffuse <(pdftotext -layout old.pdf /dev/stdout) <(pdftotext -layout new.pdf /dev/stdout)

http://diffuse.sourceforge.net/

Espero que ayude.

phyatt
fuente
4

Si tiene 2-3 archivos PDF enormes (o epub u otros formatos, lea a continuación) para comparar, entonces es posible combinar el poder de:

  1. calibre (para convertir su fuente a texto)

  2. meld (para buscar visualmente las diferencias entre los archivos de texto)

  3. paralelo (para usar todos los núcleos de su sistema para acelerar)

El siguiente script acepta como entrada cualquiera de los siguientes formatos de archivo: MOBI, LIT, PRC, EPUB, ODT, HTML, CBR, CBZ, RTF, TXT, PDF y LRS.

Si no está instalado, instale meld, calibre y paralelo:

#install packages
sudo apt-get -y install meld calibre parallel

Para poder ejecutar el código desde cualquier lugar de su computadora, guarde el siguiente código en un archivo llamado "diffepub" (sin extensiones) dentro del directorio "/ usr / local / bin".

usage="
*** usage:

diffepub - compare text in two files. Valid format for input files are:
MOBI, LIT, PRC, EPUB, ODT, HTML, CBR, CBZ, RTF, TXT, PDF and LRS.

diffepub -h | FILE1 FILE2

-h print this message

Example:
diffepub my_file1.pdf my_file2.pdf
diffepub my_file1.epub my_file2.epub

v0.2 (added parallel and 3 files processing)
"

#parse command line options
while getopts "h" OPTIONS ; do
  case ${OPTIONS} in
    h|-help) echo "${usage}"; exit;;
  esac
done
shift $(($OPTIND - 1))

#check if first 2 command line arguments are files
if [ -z "$1" ] || [ -z "$2" ] || [ ! -f "$1" ] || [ ! -f "$2" ]
then
  echo "ERROR: input files do not exist."
  echo
  echo "$usage"
  exit
fi



#create temporary files (first & last 10 characters of
# input files w/o extension)
file1=`basename "$1" | sed -r -e '
s/\..*$//                     #strip file extension
s/(^.{1,10}).*(.{10})/\1__\2/ #take first-last 10 chars
s/$/_XXX.txt/                 #add tmp file extension
'`
TMPFILE1=$(mktemp --tmpdir "$file1")

file2=`basename "$2" | sed -r -e '
s/\..*$//                     #strip file extension
s/(^.{1,10}).*(.{10})/\1__\2/ #take first-last 10 chars
s/$/_XXX.txt/                 #add tmp file extension
'`
TMPFILE2=$(mktemp --tmpdir "$file2")

if [ "$#" -gt 2 ] 
then
  file3=`basename "$3" | sed -r -e '
  s/\..*$//                     #strip file extension
  s/(^.{1,10}).*(.{10})/\1__\2/ #take first-last 10 chars
  s/$/_XXX.txt/                 #add tmp file extension
  '`
  TMPFILE3=$(mktemp --tmpdir "$file3")
fi

#convert to txt and compare using meld
doit(){ #to solve __space__ between filenames and parallel
  ebook-convert $1
}
export -f doit
if [ "$#" -gt 2 ] 
then
  (parallel doit ::: "$1 $TMPFILE1" \
                     "$2 $TMPFILE2" \
                     "$3 $TMPFILE3" ) &&
  (meld "$TMPFILE1" "$TMPFILE2" "$TMPFILE3")
else
  (parallel doit ::: "$1 $TMPFILE1" \
                     "$2 $TMPFILE2" ) &&
  (meld "$TMPFILE1" "$TMPFILE2")
fi

Asegúrese de que el propietario sea su usuario y que tenga permisos de ejecución:

sudo chown $USER:$USER /usr/local/bin/diffepub
sudo chmod 700 /usr/local/bin/diffepub

Para probarlo, solo escribe:

diffepub FILE1 FILE2

Lo pruebo para comparar 2 revisiones de un pdf de +1600 páginas y funciona perfecto. Debido a que calibre está escrito usando python para la portabilidad, tomó 10 minutos convertir ambos archivos a texto. Lento, pero confiable.

luis_js
fuente