Unterschied von zwei PDF-Dateien?

39

Ich suche ein gutes Programm, um mir die Unterschiede zwischen zwei ähnlichen PDF-Dateien zu zeigen. Insbesondere suche ich nach etwas, das nicht nur auf einer ASCII-Version (mit "pdftotext") der Dateien diff ausführt. Das macht pdfdiff.py .

Krumpelstilzchen
quelle
Muss es Open Source und kostenlos sein?
Rinzwind
@Rinzwind: Das wäre natürlich vorzuziehen.
krumpelstiltskin
inetsoftware.de/other-products/pdf-content-comparer/... 2.2 hier steht, dass es unter Linux verwendet werden kann (runPDFC.sh), aber die Datei ist nicht im Archiv (nur eine Fledermaus ...), aber es ist Java so vielleicht umbenennen (?)
Rinzwind
@ Rinzwind: Ich weiß nicht genug über Java, um herauszufinden, warum es nicht läuft. Ich mache: Java-CP. -jar PDFC.jar aber bekomme einen java.lang.NoClassDefFoundError :(
krumpelstiltskin
@ Rinzwind: Ich habe dies auf Windows ausgeführt; Das Programm ist schrecklich. Es erstellt PNG, die unleserlich sind.
krumpelstiltskin

Antworten:

28

Sie können dafür DiffPDF verwenden . Aus der Beschreibung:

DiffPDF wird zum Vergleichen von zwei PDF-Dateien verwendet. Standardmäßig wird der Vergleich des Texts auf jedem Seitenpaar durchgeführt, der Vergleich des Erscheinungsbilds der Seiten wird jedoch auch unterstützt (z. B. wenn ein Diagramm geändert oder ein Absatz neu formatiert wird). Es ist auch möglich, bestimmte Seiten oder Seitenbereiche zu vergleichen. Wenn beispielsweise zwei Versionen einer PDF-Datei vorhanden sind, eine mit den Seiten 1 bis 12 und die andere mit den Seiten 1 bis 13, da eine zusätzliche Seite als Seite 4 hinzugefügt wurde, können diese durch Angabe von zwei Seitenbereichen 1 verglichen werden -12 für den ersten und 1-3, 5-13 für den zweiten. Dadurch wird DiffPDF veranlasst, Seiten in den Paaren (1, 1), (2, 2), (3, 3), (4, 5), (5, 6) usw. mit (12, 13) zu vergleichen.

qbi
quelle
2
Das ist das Beste, was ich gesehen habe. Das einzige Problem, das ich sehe, ist, dass es pdfs Seite für Seite vergleicht. Wenn Sie also einen Absatz auf Seite 1 hinzufügen, stimmen Anfang und Ende jeder Seite danach nicht überein. :(
krumpelstiltskin
3
Ich denke der Link ist nicht mehr korrekt. Die neue Version 3. * scheint nur für Windows verfügbar zu sein. Die alte Version 2. * kann jedoch weiterhin über installiert werden sudo apt-get install diffpdf.
Peq
22

Ich habe gerade einen Hack herausgefunden, um DiffPDF (das von @qbi vorgeschlagene Programm) für mehr als kleine Änderungen nutzbar zu machen. Was ich tue, ist, alle Seiten pdfs mit pdfjam zu einer langen Schriftrolle zu verketten und dann die Schriftrollen zu vergleichen. Es funktioniert auch, wenn große Abschnitte entfernt oder eingefügt werden!

Hier ist ein Bash-Skript, das die Arbeit erledigt:

#!/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
Krumpelstilzchen
quelle
2
Ich habe Ihr Skript Whitespace-kompatibel gemacht und einzigartige Tempfiles hinzugefügt. Ich hoffe es macht dir nichts aus.
Glutanimate
2
Es wurde auch ein kleiner Fehler behoben, bei dem das Skript eine leere Textdatei im Arbeitsverzeichnis erstellte. (
Denken Sie
2
Eine letzte Bemerkung: Dieses Skript funktioniert nur für Dokumente im Format DIN A4. Sie müssen den PAGEHEIGHT-Wert anpassen, damit er mit kleineren Dokumenten funktioniert. Ich bin sicher, es gibt eine Möglichkeit, dies zu automatisieren, aber ich weiß nicht, wie atm.
Glutanimate
2
Vielen Dank für die Verbesserungen @Glutanimate. Ich habe die Unterstützung für den Vergleich von PDFs mit beliebigen und unterschiedlichen Größen hinzugefügt (sofern die Seiten in jedem PDF eine einheitliche Größe haben).
krumpelstiltskin
Der Einfachheit halber wurde es
Tim Abell
8

Auch wenn dies das Problem nicht direkt löst, ist dies eine gute Möglichkeit, alles mit wenigen Abhängigkeiten von der Kommandozeile aus zu erledigen:

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

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

Es funktioniert sehr gut für einfache PDF-Vergleiche. Wenn Sie eine neuere Version von pdftotext haben, können Sie es -bboxstattdessen versuchen -layout.

In Bezug auf unterschiedliche Programme verwende ich gerne diffuse, daher ändert sich der Befehl geringfügig:

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

http://diffuse.sourceforge.net/

Hoffentlich hilft das.

phyatt
quelle
3

Wenn Sie 2-3 große PDF-Dateien (oder Epub-Dateien oder andere Formate, siehe unten) zum Vergleichen haben, können Sie die folgenden Funktionen kombinieren:

  1. Kaliber (um Ihre Quelle in Text umzuwandeln)

  2. meld (um visuell nach den Unterschieden zwischen den Textdateien zu suchen)

  3. parallel (um alle Systemkerne zur Beschleunigung zu verwenden)

Das folgende Skript akzeptiert als Eingabe eines der folgenden Dateiformate: MOBI, LIT, PRC, EPUB, ODT, HTML, CBR, CBZ, RTF, TXT, PDF und LRS.

Wenn nicht installiert, installieren Sie meld, calibre und parallel:

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

Speichern Sie den folgenden Code in einer Datei mit dem Namen "diffepub" (ohne Erweiterungen) im Verzeichnis "/ usr / local / bin", um den Code von einem beliebigen Ort auf Ihrem Computer ausführen zu können.

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

Stellen Sie sicher, dass der Eigentümer Ihr Benutzer ist und über Ausführungsberechtigungen verfügt:

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

Geben Sie zum Testen einfach Folgendes ein:

diffepub FILE1 FILE2

Ich teste es, um 2 Revisionen eines +1600 Seiten PDF zu vergleichen und es funktioniert perfekt. Da Calibre aus Gründen der Portabilität mit Python geschrieben wurde, dauerte die Konvertierung beider Dateien in Text 10 Minuten. Langsam, aber zuverlässig.

luis_js
quelle