Различаются два файла PDF?

39

Я ищу хорошую программу, чтобы показать мне различия между двумя похожими файлами PDF. В частности, я ищу что-то, что не просто запускает diff для версии ascii (с "pdftotext") файлов. Это то, что делает pdfdiff.py .

krumpelstiltskin
источник
Это должно быть с открытым исходным кодом и бесплатно?
Rinzwind
@Rinzwind: Это было бы предпочтительнее, конечно.
krumpelstiltskin
inetsoftware.de/other-products/pdf-content-comparer/… 2.2 здесь говорится, что он может быть использован под Linux (runPDFC.sh), но файл не находится в архиве (только bat ...), но это java, так что может быть переименовать его (?)
Rinzwind
@Rinzwind: я не знаю достаточно о Java, чтобы понять, почему он не работает. я делаю: java -cp. -jar PDFC.jar, но получите java.lang.NoClassDefFoundError :(
krumpelstiltskin
@Rinzwind: я запустил это на окнах; программа ужасная это создает PNG, которые неразборчивы.
krumpelstiltskin

Ответы:

28

Вы можете использовать DiffPDF для этого. Из описания:

DiffPDF используется для сравнения двух файлов PDF. По умолчанию сравнение выполняется для текста на каждой паре страниц, но сравнение внешнего вида страниц также поддерживается (например, если диаграмма изменена или переформатирован абзац). Также возможно сравнение отдельных страниц или диапазонов страниц. Например, если существует две версии файла PDF, одна со страницами 1-12, а другая со страницами 1-13 из-за добавления дополнительной страницы в качестве страницы 4, их можно сравнить, указав два диапазона страниц: 1 -12 для первого и 1-3, 5-13 для второго. Это заставит DiffPDF сравнивать страницы в парах (1, 1), (2, 2), (3, 3), (4, 5), (5, 6) и т. Д. С (12, 13).

QBi
источник
2
Это лучшее, что я видел. Единственная проблема, которую я вижу, заключается в том, что она сравнивает страницу в формате PDF. Таким образом, если вы добавите абзац, скажем, на странице 1, начало и конец каждой страницы после этого не совпадут. :(
krumpelstiltskin
3
Я думаю, что ссылка больше не верна. Новая версия 3. *, кажется, доступна только для Windows. sudo apt-get install diffpdfХотя старая версия 2. * все еще может быть установлена ​​через .
августа
22

Я только что понял, как сделать DiffPDF (программу, предложенную @qbi) пригодной для более чем незначительных изменений. Что я делаю, это объединяю все страницы PDF в длинную прокрутку, используя pdfjam, а затем сравниваю прокрутки . Это работает, даже когда большие разделы удалены или вставлены!

Вот скрипт bash, который делает эту работу:

#!/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
источник
2
Я сделал ваш скрипт совместимым с пробелами и добавил уникальные временные файлы. Надеюсь, ты не против.
Glutanimate
2
Также исправлена ​​небольшая ошибка, при которой скрипт создавал пустой текстовый файл в рабочем каталоге. (не забывайте всегда использовать двойные скобки с операторами if, которые используют «>» и связанные с ними операнды.)
Glutanimate
2
Последнее замечание: этот скрипт будет работать нормально только для документов формата DIN A4. Вам придется настроить значение PAGEHEIGHT, чтобы оно работало с небольшими документами. Я уверен, что есть способ автоматизировать это, но не знаю как.
Glutanimate
2
Спасибо за внесение улучшений @Glutanimate. Я добавил поддержку для сравнения PDF-файлов произвольных и разных размеров (при условии, что страницы в каждом PDF-файле имеют одинаковый размер).
krumpelstiltskin
сохранено в сущности для удобства gist.github.com/timabell/9616807b2fe3fa60f234
Тим Абелл
8

Хотя это не решает проблему напрямую, вот хороший способ сделать все это из командной строки с несколькими зависимостями:

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

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

Это работает очень хорошо для базовых сравнений PDF. Если у вас есть более новая версия pdftotext, вы можете попробовать -bboxвместо -layout.

Что касается программ diffing, мне нравится использовать diffuse, поэтому команда немного меняется:

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

http://diffuse.sourceforge.net/

Надеюсь, это поможет.

phyatt
источник
4

Если у вас есть 2-3 больших файла pdf (или epub или другие форматы, см. Ниже) для сравнения, то можно объединить следующие возможности:

  1. калибр (для преобразования вашего источника в текст)

  2. meld (для визуального поиска различий между текстовыми файлами)

  3. параллельно (чтобы ускорить использование всех ядер вашей системы)

Ниже скрипт принимает в качестве входных данных любой из следующих форматов файлов: MOBI, LIT, PRC, EPUB, ODT, HTML, CBR, CBZ, RTF, TXT, PDF и LRS.

Если не установлено, то установите соединение, калибр и параллель:

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

Чтобы иметь возможность выполнять код из любой точки вашего компьютера, сохраните следующий код в файле с именем «difpub» (без расширений) в каталоге «/ 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

Убедитесь, что владелец является вашим пользователем и у него есть права на выполнение:

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

Чтобы проверить это, просто наберите:

diffepub FILE1 FILE2

Я проверяю его, чтобы сравнить 2 ревизии +1600 страниц PDF, и он отлично работает. Поскольку Calibre написан с использованием Python для переносимости, преобразование обоих файлов в текст заняло 10 минут. Медленно, но надежно.

luis_js
источник