PDF在linux命令行上进行比较

Chr*_*erl 27 linux pdf comparison ghostscript

我正在寻找一个Linux命令行工具来比较两个PDF文件并将差异保存为PDF文件.该工具应该在批处理过程中创建diff-pdf.PDF文件是构建计划,因此纯文本比较不起作用.

就像是:

<tool> file1.pdf file2.pdf -o diff-out.pdf
Run Code Online (Sandbox Code Playgroud)

我找到的大多数工具都将PDF转换为图像并进行比较,但只能使用GUI.

任何其他解决方案也欢迎.

Kur*_*fle 40

我编写了自己的脚本,它的功能与您要求的类似.该脚本使用4个工具来实现其目标:

  1. ImageMagick的compare命令
  2. pdftk实用程序(如果你有PDF的多页)
  3. Ghostscript(可选)
  4. md5sum (可选的)

将它移植到.batDOS/Windows 的批处理文件应该很容易.

但首先请注意: 这仅适用于页面/媒体大小相同的PDF.比较在两个输入PDF之间逐个像素地完成.生成的文件是显示"diff"的图像,如下所示:

  • 保持不变的每个像素变为白色.
  • 更改的每个像素都涂成红色.

该差异图像保存为新的PDF,以便在不同的操作系统平台上更好地访问.

我正在使用它来发现PDF处理中的字体替换发挥作用时的最小页面显示差异.

虽然它们在MD5哈希值和/或文件大小上有所不同,但可能会发生,PDF之间没有明显差异.在这种情况下,"diff"输出PDF页面将变为全白.您可以自动发现此情况,因此您只需通过自动删除全白PDF来直观地调查非白色PDF.

以下是构建基块:

PDFTK

使用此命令行实用程序将多页PDF文件拆分为多个单页PDF:

pdftk  file_1.pdf  burst  output  somewhere/file_1---page_%03d.pdf
pdftk  file_2.pdf  burst  output  somewhere/file_2---page_%03d.pdf
Run Code Online (Sandbox Code Playgroud)

如果仅比较1页PDF,则此构建块是可选的.既然你谈到"建设计划",情况可能就是这样.

相比

使用ImageMagick中的此命令行实用程序为每个页面创建"diff"PDF页面:

compare \
       -verbose \
       -debug coder \
       -log "%u %m:%l %e" \
        somewhere/file_1---page_001.pdf \
        somewhere/file_2---page_001.pdf \
       -compose src \
        somewhereelse/file_1--file_2---diff_page_001.pdf
Run Code Online (Sandbox Code Playgroud)

Ghostscript的

由于自动插入的元数据(例如当前日期+时间),PDF输出不适用于基于MD5hash的文件比较.

如果要自动发现diff PDF由纯白页组成的所有情况,则应使用bmp256输出设备将PDF页面转换为无元数据的位图格式.你可以这样做:

首先,找出PDF的页面大小格式.同样,这个小实用程序identify是任何ImageMagick安装的一部分:

 identify \
   -format "%[fx:(w)]x%[fx:(h)]" \
    somewhereelse/file_1--file_2---diff_page_001.pdf
Run Code Online (Sandbox Code Playgroud)

您可以将此值存储在这样的环境变量中:

 export my_size=$(identify \
   -format "%[fx:(w)]x%[fx:(h)]" \
    somewhereelse/file_1--file_2---diff_page_001.pdf)
Run Code Online (Sandbox Code Playgroud)

现在Ghostscript开始使用命令行,其中包含上面发现的页面大小,因为它存储在变量中:

 gs \
   -o somewhereelse/file_1--file_2---diff_page_001.ppm \
   -sDEVICE=ppmraw \
   -r72 \
   -g${my_size} \
    somewhereelse/file_1--file_2---diff_page_001.pdf
Run Code Online (Sandbox Code Playgroud)

这为您提供了一个PPM(Portable PixMap),其分辨率为原始PDF页面的72 dpi.72 dpi通常足以满足我们的需求...接下来,创建一个具有相同页面大小的纯白色PPM页面:

 gs \
   -o somewhereelse/file_1--file_2---whitepage_001.ppm \
   -sDEVICE=ppmraw \
   -r72 \
   -g${my_size} \
   -c "showpage"
Run Code Online (Sandbox Code Playgroud)

-c "showpage"部分是一个PostScript命令,它告诉Ghostscript只发出一个空页面.

MD5总和

使用MD5哈希自动将原始PPM与白页PPM进行比较.如果它们相同,您可以节省地假设PDF之间没有差异,因此重命名或删除diff-PDF:

 MD5_1=$(md5sum somewhereelse/file_1--file_2---diff_page_001.ppm | awk '{print $1}')
 MD5_2=$(md5sum somewhereelse/file_1--file_2---whitepage_001.ppm | awk '{print $1}')

 if [ "x${MD5_1}" == "x${MD5_2}" ]; then 
     mv  \
       somewhereelse/file_1--file_2---diff_page_001.pdf \
       somewhereelse/file_1--file_2---NODIFFERENCE_page_001.pdf # rename all-white PDF
     rm  \
       somewhereelse/file_1--file_2---*_page_001.ppm            # delete both PPMs
 fi
Run Code Online (Sandbox Code Playgroud)

这使您不必视觉检查没有任何差异的"差异PDF".

  • "你自己的脚本"可以在某处下载吗?作为一个要点,例如?) (4认同)
  • 好主意!这里还有更多。要验证您的文件(或其页面)是否是纯白色,您可以使用直方图: `convert file.pdf -format %c histogram:info: | 如果页面上有白色以外的内容, grep -Ev '^$|255,255,255,' &gt; /dev/null` 将返回“0”。您还可以通过使用 subsctripion 直接对 PDF 页面使用“compare”:“compare file1.pdf[42] file2.pdf[42] -compose src output.png”。现在全部放在一起: `compare "$src[$i]" "$dst[$i]" -compose src -format %c histogram:info: | 如果这些 PDF 中的第 #i 页不同, grep -Ev '^$|255,255,255,' &gt; /dev/null` 将为您带来成功。 (2认同)

xev*_*ent 24

这是一个黑客做到这一点.

pdftotext file1.pdf
pdftotext file2.pdf
diff file1.txt file2.txt
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,但 pdf 文件是施工计划,所以上面没有文字。 (4认同)
  • 以下是与答案中列出的相同的命令,但在一行中:`vimdiff &lt;(pdftotext /path/to/pdf-file-1 -) &lt;(pdftotext /path/to/pdf-file-2 -)` (2认同)

Chr*_*erl 6

用(全能)imagemagick和pdftk完成2行:

compare -verbose -debug coder $PDF_1 $PDF_2 -compose src $OUT_FILE.tmp
pdftk $OUT_FILE.tmp background $PDF_1 output $OUT_FILE
Run Code Online (Sandbox Code Playgroud)

选项-verbose和-debug是可选的.

  • compare创建一个PDF,diff为红色像素.
  • pdftk将diff-pdf与后台PDF_1合并

  • 好...你从我的答案中提取了核心命令行并剥离了其余部分.也许您不需要比较多页PDF和我的方法所涵盖的一些其他角落案例...... (15认同)