Difere de dois arquivos pdf?

39

Estou procurando um bom programa para me mostrar as diferenças entre dois arquivos pdf semelhantes. Em particular, estou procurando algo que não execute apenas diff em uma versão ascii (com "pdftotext") dos arquivos. É isso que o pdfdiff.py faz.

krumpelstiltskin
fonte
Ele precisa ser de código aberto e gratuito?
Rinzwind
@Rinzwind: Isso seria preferível, é claro.
Krumpelstiltskin
inetsoftware.de/other-products/pdf-content-comparer/… 2.2 aqui afirma que pode ser usado no Linux (runPDFC.sh), mas o arquivo não está no arquivo morto (apenas um bastão ...), mas é em java talvez renomeá-lo (?)
Rinzwind
@Rinzwind: eu não sei o suficiente sobre java para descobrir por que ele não está sendo executado. Eu faço: java -cp. -jar PDFC.jar mas obter um java.lang.NoClassDefFoundError :(
krumpelstiltskin
@Rinzwind: corri isso no Windows; o programa é terrível. ele cria png ilegível.
Krumpelstiltskin #

Respostas:

28

Você pode usar o DiffPDF para isso. A partir da descrição:

O DiffPDF é usado para comparar dois arquivos PDF. Por padrão, a comparação é do texto em cada par de páginas, mas a comparação da aparência das páginas também é suportada (por exemplo, se um diagrama for alterado ou um parágrafo reformatado). Também é possível comparar páginas ou intervalos de páginas específicos. Por exemplo, se houver duas versões de um arquivo PDF, uma com as páginas 1 a 12 e a outra com as páginas 1 a 13 por causa da adição de uma página como página 4, elas poderão ser comparadas especificando dois intervalos de páginas, 1 -12 para o primeiro e 1-3, 5-13 para o segundo. Isso fará com que o DiffPDF compare as páginas nos pares (1, 1), (2, 2), (3, 3), (4, 5), (5, 6) e assim por diante, com (12, 13).

qbi
fonte
2
Este é o melhor que eu já vi. O único problema que vejo é que ele compara os PDFs página por página. Portanto, se você adicionar um parágrafo em, digamos, página 1, o início e o final de cada página depois disso não corresponderá. :(
krumpelstiltskin
3
Eu acho que o link não está mais correto. A nova versão 3. * parece estar disponível apenas para Windows. A versão antiga 2. * ainda pode ser instalada via sudo apt-get install diffpdf.
peq
22

Acabei de descobrir um truque para tornar o DiffPDF (o programa sugerido pelo @qbi) utilizável por mais que pequenas alterações. O que faço é concatenar todas as páginas em PDFs em um rolagem longa usando o pdfjam e depois compará-las. Funciona mesmo quando grandes seções são removidas ou inseridas!

Aqui está um script bash que faz o trabalho:

#!/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
fonte
2
Criei seu script compatível com espaço em branco e adicionei arquivos temporários exclusivos. Espero que você não se importe.
Glutanimado
2
Também foi corrigido um pequeno bug em que o script criava um arquivo de texto vazio no diretório de trabalho. (lembre-se de sempre usar colchetes duplos com instruções if que usam ">" e operandos relacionados.)
Glutanimado
2
Uma última observação: esse script funcionará bem apenas para documentos de tamanho DIN A4. Você precisará ajustar o valor PAGEHEIGHT para que ele funcione com documentos menores. Tenho certeza de que há uma maneira de automatizar isso, mas não sei como atm.
Glutanimate
2
Obrigado por fazer as melhorias @Glutanimate. Adicionei suporte para comparação de PDFs de tamanhos arbitrários e diferentes (contanto que as páginas de cada PDF sejam de tamanho uniforme).
Krumpelstiltskin
salvo em uma essência por conveniência gist.github.com/timabell/9616807b2fe3fa60f234
Tim Abell
8

Mesmo que isso não resolva o problema diretamente, eis uma boa maneira de fazer tudo isso na linha de comando com poucas dependências:

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

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

Funciona muito bem para comparações básicas de pdf. Se você possui uma versão mais recente do pdftotext, pode tentar em -bboxvez de -layout.

No que diz respeito a programas diferentes, eu gosto de usar difuso, então o comando muda um pouco:

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

http://diffuse.sourceforge.net/

Espero que ajude.

phyatt
fonte
4

Se você tiver 2 a 3 arquivos PDF enormes (ou epub ou outros formatos, leia abaixo) para comparar, será possível combinar o poder de:

  1. calibre (para converter sua fonte em texto)

  2. meld (para procurar visualmente as diferenças entre os arquivos de texto)

  3. paralelo (para usar todos os núcleos do sistema para acelerar)

O script abaixo aceita como entrada qualquer um dos seguintes formatos de arquivo: MOBI, LIT, PRC, EPUB, ODT, HTML, CBR, CBZ, RTF, TXT, PDF e LRS.

Se não estiver instalado, instale meld, calibre e paralelo:

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

Para poder executar o código de qualquer lugar do seu computador, salve o código a seguir em um arquivo chamado "diffepub" (sem extensões) dentro do diretório "/ 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

Verifique se o proprietário é seu usuário e se possui permissões de execução:

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

Para testá-lo, basta digitar:

diffepub FILE1 FILE2

Eu o testo para comparar duas revisões de um pdf de +1600 páginas e funciona perfeitamente. Como o calibre é escrito usando python para portabilidade, levou 10 minutos para converter os dois arquivos em texto. Lento, mas confiável.

luis_js
fonte