Diff de deux fichiers pdf?

39

Je cherche un bon programme pour me montrer les différences entre deux fichiers pdf similaires. En particulier, je cherche quelque chose qui ne se contente pas de lancer diff sur une version ascii (avec "pdftotext") des fichiers. C'est ce que fait pdfdiff.py .

Krumpelstiltskin
la source
Doit-il être open source et gratuit?
Rinzwind
@Rinzwind: Ce serait préférable, bien sûr.
krumpelstiltskin
inetsoftware.de/other-products/pdf-content-comparer/… 2.2 indique ici qu'il peut être utilisé sous Linux (runPDFC.sh) mais que le fichier ne se trouve pas dans l'archive (seulement une batte ...) mais qu'il est java peut-être le renommer (?)
Rinzwind
@Rinzwind: je ne connais pas suffisamment Java pour comprendre pourquoi il ne fonctionne pas. je fais: java -cp. -jar PDFC.jar mais obtenez un java.lang.NoClassDefFoundError :(
krumpelstiltskin
@Rinzwind: je l'ai couru sur Windows; le programme est terrible. cela crée des png illisibles.
krumpelstiltskin

Réponses:

28

Vous pouvez utiliser DiffPDF pour cela. De la description:

DiffPDF est utilisé pour comparer deux fichiers PDF. Par défaut, la comparaison porte sur le texte de chaque paire de pages, mais la comparaison de l'apparence des pages est également prise en charge (par exemple, si un diagramme est modifié ou un paragraphe reformaté). Il est également possible de comparer des pages ou des plages de pages particulières. Par exemple, s’il existe deux versions d’un fichier PDF, l’une avec les pages 1-12 et l’autre avec les pages 1-13 en raison de l’ajout d’une page supplémentaire en tant que page 4, elles peuvent être comparées en spécifiant deux plages de pages, 1 -12 pour le premier et 1-3, 5-13 pour le second. DiffPDF comparera ainsi les pages des paires (1, 1), (2, 2), (3, 3), (4, 5), (5, 6), etc., à (12, 13).

qbi
la source
2
C'est le meilleur que j'ai vu. Le seul problème que je vois est qu'il compare le pdfs page par page. Donc, si vous ajoutez un paragraphe à la page 1, par exemple, le début et la fin de chaque page ne correspondent pas. :(
krumpelstiltskin
3
Je pense que le lien n'est plus correct. La nouvelle version 3. * semble être disponible uniquement pour Windows. L'ancienne version 2. * peut toujours être installée via sudo apt-get install diffpdf.
peq
22

Je viens juste de trouver un moyen de rendre DiffPDF (le programme suggéré par @qbi) utilisable pour des modifications autres que mineures. Ce que je fais est concaténer toutes les pages pdfs dans un long rouleau en utilisant pdfjam et ensuite comparer les parchemins. Cela fonctionne même lorsque de grandes sections sont enlevées ou insérées!

Voici un script bash qui fait le travail:

#!/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
la source
2
J'ai rendu votre script compatible avec les espaces et ajouté des fichiers temporaires uniques. J'espère que ça ne vous dérange pas.
Glutanimate
2
Également corrigé un petit bug dans lequel le script créerait un fichier texte vide dans le répertoire de travail. (N'oubliez pas de toujours utiliser des crochets doubles avec les déclarations if qui utilisent ">" et les opérandes associés.)
Glutanimate
2
Une dernière remarque: ce script ne fonctionnera que pour les documents de format DIN A4. Vous devrez ajuster la valeur PAGEHEIGHT pour que cela fonctionne avec des documents plus petits. Je suis sûr qu'il existe un moyen d'automatiser cela, mais je ne sais pas comment.
Glutanimate
2
Merci d'avoir apporté les améliorations @ Glutanimate. J'ai ajouté un support pour la comparaison de fichiers PDF de tailles arbitraires et différentes (à condition que les pages de chaque fichier PDF soient de taille uniforme).
krumpelstiltskin
enregistré sur un point essentiel pour la commodité gist.github.com/timabell/9616807b2fe3fa60f234
Tim Abell
8

Même si cela ne résout pas le problème directement, voici un bon moyen de faire tout cela en ligne de commande avec quelques dépendances:

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

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

Cela fonctionne vraiment bien pour les comparaisons de base en pdf. Si vous avez une version plus récente de pdftotext, vous pouvez essayer -bboxau lieu de -layout.

Pour ce qui est des programmes, j'aime utiliser diffuse, la commande change donc très légèrement:

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

http://diffuse.sourceforge.net/

J'espère que ça t'as aidé.

Phyatt
la source
4

Si vous avez 2 ou 3 énormes fichiers pdf (ou epub ou autres formats, lisez ci-dessous) à comparer, il est possible de combiner la puissance de:

  1. calibre (pour convertir votre source en texte)

  2. meld (pour rechercher visuellement les différences entre les fichiers texte)

  3. parallèle (utiliser tous les cœurs de votre système pour accélérer)

Le script ci-dessous accepte en entrée l’un des formats de fichier suivants: MOBI, LIT, PRC, EPUB, ODT, HTML, CBR, CBZ, RTF, TXT, PDF et LRS.

S'il n'est pas installé, installez alors meld, calibre et parallèle:

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

Pour pouvoir exécuter le code de n’importe où sur votre ordinateur, enregistrez le code suivant dans un fichier nommé "diffepub" (sans extension) dans le répertoire "/ 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

Assurez-vous que le propriétaire est votre utilisateur et qu'il dispose des autorisations d'exécution:

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

Pour le tester, tapez simplement:

diffepub FILE1 FILE2

Je l'ai testé pour comparer 2 révisions d'un pdf de +1600 pages et cela fonctionne parfaitement. Comme calibre est écrit en python pour la portabilité, il a fallu 10 minutes pour convertir les deux fichiers en texte. Lent mais fiable.

luis_js
la source