查找 PDF 文档中的重复页面

查找 PDF 文档中的重复页面

我有一个由(大量)小文档串联而成的 pdf 文档。例如,1.pdf、2.pdf 和 3.pdf。问题是 1.pdf 的最后一页也是 2.pdf 的第一页,而 2.pdf 的最后一页也是第一页……你懂的。

因此,加入后,我得到了包含大量重复页面的 pdf 文档。该文档大约有 12000 页(!!)。有没有办法自动检测重复页面并删除它们?

或者有什么想法可以让这一切变得更容易一些?

答案1

如果您的“相同”页面在屏幕上呈现完全相同的视觉外观,则以下算法方法可以找出重复项:

  1. 使用 Ghostscript 将每页转换为低分辨率 TIFF 或 JPEG 文件(fe 使用 72dpi)。
  2. 如果您使用 TIFF:运行以下任一命令命令行实用程序来“规范化” TIFF 元数据。
  3. 在每个 TIFF 或 JPEG 页面上运行 md5sum.exe 并记住每个页面的 Md5sum。
  4. 对 MD5sum 列表进行排序以查找重复的页面。
  5. 记住删除所有重复的页码。
  6. pdftk.exe在原始 PDF 上运行命令行以删除重复项。

您可以使用任何您喜欢的语言编写该算法(甚至可以在 Windows 上进行批处理或在 Linux/Unix/MacOSX 上进行 bash)。

第一的: 关于使用 Ghostscript 的一些注意事项。创建 1200 个 TIFF(或 JPEG)页面(在 Linux 上可以使用gs代替gswin32c):

gswin32c.exe ^
      -dBATCH -dNOPAUSE -dSAFER ^
      -sDEVICE=tiffg4 ^
      -sOutputFile=C:\temp\tiffs\page-%06d.tif ^
      -r72x72 ^
      12000pages.pdf ^
# use -sDEVICE=jpeg to create *.jpeg files + adapt -sOutputFile= accordingly
# page-%06d.tif creates TIFFs named page-000001.tif through page-012000.tif* 

第二: 关于使用(免费提供的)libtiff 实用程序的要求的一些说明。Ghostscript 创建 TIFF 页面时,会记录其当前版本、日期和时间以及 TIFF 中的其他元数据。这可能会破坏您的 MD5 检查,因为原本相同的 TIFF 可能带有不同的日期/时间戳。因此需要“规范化”这些。使用tiffinfo page-000001.tiftiffdump page-000001.tif了解我的意思。您可能会看到类似以下内容的内容:

c:\downloads> tiffdump.exe page-000001.tif
  page-000001.tif:
  Magic: 0x4949 <little-endian> Version: 0x2a
  Directory 0: offset 2814 (0xafe) next 0 (0)
  SubFileType (254) LONG (4) 1<2>
  ImageWidth (256) SHORT (3) 1<595>
  ImageLength (257) SHORT (3) 1<842>
  BitsPerSample (258) SHORT (3) 1<1>
  Compression (259) SHORT (3) 1<4>
  Photometric (262) SHORT (3) 1<0>
  FillOrder (266) SHORT (3) 1<1>
  StripOffsets (273) LONG (4) 8<8 341 1979 1996 2013 2030 2047 2064>
  Orientation (274) SHORT (3) 1<1>
  SamplesPerPixel (277) SHORT (3) 1<1>
  RowsPerStrip (278) SHORT (3) 1<109>
  StripByteCounts (279) LONG (4) 8<333 1638 17 17 17 17 17 13>
  XResolution (282) RATIONAL (5) 1<72>
  YResolution (283) RATIONAL (5) 1<72>
  PlanarConfig (284) SHORT (3) 1<1>
  Group4Options (293) LONG (4) 1<0>
  ResolutionUnit (296) SHORT (3) 1<2>
  PageNumber (297) SHORT (3) 2<0 0>
  Software (305) ASCII (2) 21<GPL Ghostscript 8.71\0>
  DateTime (306) ASCII (2) 20<2010:06:22 04:56:12\0>

下面是在示例 TIFF 中“规范化”日期+时间字段(在我的情况下标记为“306”)的命令:

 c:\downloads> tiffset -s 306 "0000:00:00 00:00:00" ex001.tif

因此,约会时间字段现已改变:

 c:\pa>tiffdump ex001.tif | findstr DateTime
   DateTime (306) ASCII (2) 20<0000:00:00 00:00:00\0>

现在循环遍历所有 TIFF 来规范化所有 DateTime 字段:

 c:\downloads> for /l %i in (C:\temp\tiffs\*.tif) ^
                  do tiffset -s 306 "0000:00:00 00:00:00" %i

第三和第四个: 运行 md5sum.exe 并对文件列表进行排序以查找重复项。以下是要使用的命令行:

 c:\downloads> md5sum.exe C:\temp\tiffs\*.tif | sort

因此,您应该很容易看到哪些文件/页面具有相同的 MD5 哈希值。它看起来类似于以下内容:

c:\> md5sum.exe c:/temp/tiffs/page-0*.tif
  [....]
  fae9fa136c4f7ecca23b6a34d620fb02 *c:\temp\tiffs\page-000032.tif
  fae9fa136c4f7ecca23b6a34d620fb02 *c:\temp\tiffs\page-000033.tif
  fb5fef1732148d71bfff841c214cf836 *c:\temp\tiffs\page-000076.tif
  fb5fef1732148d71bfff841c214cf836 *c:\temp\tiffs\page-000077.tif
  fb86c1bdbc697eef7cb869f4e2e2957b *c:\temp\tiffs\page-000187.tif
  fb86c1bdbc697eef7cb869f4e2e2957b *c:\temp\tiffs\page-000188.tif
  fbb801ab3ef7ea33619132f97dcab045 *c:\temp\tiffs\page-000443.tif
  fbb801ab3ef7ea33619132f97dcab045 *c:\temp\tiffs\page-000444.tif
  fbc33cc0ff3e1252de1653ef2e978f94 *c:\temp\tiffs\page-000699.tif
  fbc33cc0ff3e1252de1653ef2e978f94 *c:\temp\tiffs\page-000700.tif
  fc3fd164e20bb707acddeabbc4e60f7e *c:\temp\tiffs\page-000899.tif
  fc3fd164e20bb707acddeabbc4e60f7e *c:\temp\tiffs\page-000900.tif
  [....]

我让你来自动执行该步骤。

第五和第六: 从原始 PDF 中删除所有重复的页面。假设您现在想要删除第 33、77、188、444、700 和 900 页。下面是pdftk.exe实现此目的的命令:

 c: > pdftk.exe A=12000pages.pdf ^
          cat A1-32 A34-76 A78-187 A189-443 A445-699 A701-899 A901-end ^
          output nonduplicates.pdf

*编辑:不知道为什么我一开始建议使用 TIFF——更明智的做法是使用 BMP。*

如果您使用-sDEVICE=bmp256,则-sOutputFile=C:\temp\tiffs\page-%06d.bmp无需处理我上面概述的“标准化”步骤。其余程序(md5sum ...)相同....

答案2

pdftk可以拆分/合并/删除 PDF 文件中的页面。我不知道有任何查找重复项的功能。

您可以将文档拆分为单独的页面,然后仅使用文件大小或转换为纯文本并使用差异,找到相邻的匹配页面并删除它们 - 然后重新组合成单​​个文档。

答案3

回答@Kurt Pfeifle 给出了一个非常好的解决方案。我建议进行一些小的改进。

1. 创建快照

gs -q -dBATCH -dNOPAUSE -dSAFER -sDEVICE=bmp256 -sOutputFile=%0d.bmp -r72x72 input.pdf

-q将使命令静音,这为我提高了 15% 的性能。缺点:您再也看不到进度了!

-sOutputFile=%0d.bmp将仅输出文件名中的页码,以后可以使用而无需替换文件名的部分内容

2. 并进行比较

在 UNIX 上,您可以使用重复项杰杜佩斯可能是 Windows 上的替代品,但我无法验证(某些选项不同)。

fdupes --omitfirst . | awk -F'[^0-9]*' '$0=$2' | sort -n | awk '{print $0}' ORS=','

fdupes 将在当前目录中找到重复的文件,但由于 ,只会显示第二个--omitfirst。 awk 命令将仅以逗号分隔的字符串显示页码,例如8,33,53,70,77,434,

3.然后从输入中删除页面

据我所知,像 pdftk 这样的 CLI 工具只能连接页面,因此需要一个小算法来获取页数,然后创建部分,例如1-7 9-32 ...

由于我没有时间考虑这个问题(请随意添加评论),所以我用了掌握 PDF 编辑器它有一个删除页面工具(文档 > 删除页面)。有免费版本可用!您可以轻松打开文件,复制数字,然后就大功告成了!

相关内容