在未压缩的 PDF 中进行大量内联编辑

en masse inline editing in an uncompressed PDF

我有一个很大的 PDF(~20mb,160mb,未压缩)。 我需要在其中的文本中进行查找和替换,大约 1000 次。 这是我尝试过的。

  1. 通过 SVG

    • 转换为 SVG (inkscape)
    • 逐行读取 SVG 并在文件中进行替换
    • 转换回 PDF

=> bad output, probably due to some geometric transform matrix in the SVG, the text is not well rendered

  1. 创建 ~1000 条 sed 命令

    • 解压 PDF
    • 使用 sed 命令执行每个替换
    • 重新压缩 PDF

=> way too long. each sed command takes about 20 sec, leading to several hours of process

  1. 逐行读取并替换

    • 解压 PDF
    • 逐行阅读 PDF
      • 查找要替换的文本
      • 使用 perl 替换
      • 将行写入新文件
    • 压缩新文件

=> due to left data-stream in the uncompressed PDF, the new file is apparently damaged (writing binary as lines of text)

我想知道是否可以逐行阅读未压缩的 PDF,但直接在其中进行编辑。我该怎么做?

我搜索了 perl 内联编辑,但它会立即对整个文件执行更改,而我想编辑一行。

我们非常欢迎其他想法 ;)

根据建议,我使用了CAM::PDF,这是最有效和最简单的解决方案

您可以按照中所述的 pdftk 步骤进行操作 How to find and replace text in a existing PDF file with PDFTK (or other command line application)

您可以先将 PDF 拆分成较小的文档,每个文档有几页,替换文本,然后再次将它们合并在一起 - 所有这些都使用 pdftk。

还有PDFEdit软件(http://pdfedit.cz/en/index.html)。它是一个带有脚本界面的 GUI 应用程序。您可以处理单个页面,然后使用脚本命令进行查找替换。查看它是否加载您的 PDF。

2. 和3. 没有区别。sed 逐行读取输入文件,并将更改的行写入输出文件。如果您将 -i 切换到它,sed 只会打开输入文件然后取消链接(这是 rm 所做的)然后打开具有相同名称的输出文件并写入。而已。没有魔法参与。因此,如果您通过 Perl 而不是通过 sed 破坏了内容,那么您所做的事情与通过 sed 不同。主要区别在于,您可以使 Perl 脚本更快地替换许多字符串。参见

主要技巧是您可以编译正则表达式以进行搜索和替换,这在线性时间内有效。

my %replace = ( foo => 'bar' );
my $re = join '|', map quotemeta, keys %replace;
$re = qr/($re)/;

while (<>) {
    s/$re/$replace{}/g;
}

您可以按照原来的方法使用它,但我建议在 Perl 脚本中制作它,这样您可以保留正则表达式并替换 pdf 文件之间的散列。您也可以尝试将它与 CAM::PDF. There is the example script changepagestring.pl in it. You can also look at PDF::API2 结合使用,这需要更多的工作但可能会提供更好的结果。但请记住,PDF 格式不适合修改。