我有一个 PDF 文件,其中有一个令人讨厌的水印,上面全是我的名字,这个 PDF 文件相当长。我尝试用空白替换 LibreOffice Draw 中的文本,但尽管我的名字确实以文本形式出现,但查找和替换功能似乎占用了大量的 RAM 和 CPU 时间,导致计算机性能下降。
有没有命令行方法可以从 PDF 中删除字符串?嗯... 可以sed
吗?
答案1
接受的答案仅在极少数情况下有效
抱歉,@dessert 给出的答案作为一般性建议是错误的。它不适用于 PDF 中的文本替换的一般情况(无论是否有水印),并且您必须非常幸运才能在极少数情况下遇到可以使用它的 PDF。(此外,LibreOffice 插入的水印经常被转换成矢量或像素图形,即使它们在打印或在屏幕上查看时看起来像文本......但这种情况我不会进一步讨论 - 下面我只处理 PDF 中的真实文本内容。)
原因
原因如下:
什么出现在 PDF 查看器中,其内容的可视化表示是 ASCII 文本,但 PDF 源代码中很可能不是 ASCII 文本。相反,它可能是十六进制编码的。
此外,ASCII 字符串的各个字符可能会按连续的顺序放置在页面上,但它们可以轻松地单独放置,每个字符都有自己的坐标信息散布在各个字符之间……
此外,ASCII(和非 ASCII)字符表的十六进制编码(“映射”)是不可预测的,并且可能因字体而异。
因此,在所有这些情况下,您的 sed 命令都不会成功 - 即使在解压缩 PDF 之后也不会成功。
例子
以下是“字符串”的示例水印,它如何出现在使用 LibreOffice 创建的 PDF 中:
56.8 726.989 Td /F2 16 Tf[<01>29<0203>-2<0405>6<06>-1<020507>]TJ
我将为您分析一下这意味着什么:
56.8 726.989 Td
:Td
是用于在页面上移动文本定位的操作符;56.8 726.989
是用于描述该精确位置的 x/y 坐标。/F2 16 Tf
:Tf
是一个运算符,用于将某种字体及其大小设置为当前活动字体;在这种情况下,它是用名称在其他地方标记的字体/F2
,其大小应为16
pt。[<01>29<0203>-2<0405>6<06>-1<020507>]TJ
:TJ
是一个运算符,用于显示文本,同时允许单独定位字形。根据该 PDF 特定的“charmap”表和所用字体,尖括号内十六进制代码片段的含义如下:<01>
:这就是'W'
。<0203>
:这就是'at'
。<0405>
:这就是'er'
。<06>
:这就是'm'
。<020507>
:这就是'ark'
。
29
这些十六进制片段( 、、-2
和)之间的数字是校正值6
,-1
用于确定不同字符的单独间距。
现在你向我展示如何使用其他东西替换那个“字符串”sed
... 请记住,处理任意 PDF 时,您事先并不知道编码,也不知道位置校正数字。您只能通过在编辑器中打开其源代码并分析其内容来找出答案。
执行摘要
不,没有命令行方式可以可靠地从 PDF 中删除不需要的字符串!
您只能在以下情况下执行此操作...
(a)...您是一位 PDF 专家,能够熟练阅读 PDF 源代码;
(b) ...您准备单独分析相关的 PDF 文件;
(c) ...解压 PDF 源代码后,使用文本编辑器修改其内容。
警告:目前标记为“已接受”的答案可能适用于 OP 的特定 PDF。但是,它在一般情况下不起作用。不要把它宣传的“秘诀”视为理所当然!
答案2
PDF 中显示的文本不一定是源文件中的纯文本,请参阅Kurt Pfeifle 的精彩回答了解详情。这个答案仅涵盖最简单的情况,此处描述的方法根本不适用于任何 PDF!
如果您很幸运而且它只是文本,那么您可以尝试使用sed
任何文本编辑器简单地将其删除 - 假设它说“水印”:
sed 's/watermark//g' in.pdf >out.pdf
如果你的 PDF 文件是压缩文件,则需要先将其解压缩才能使用此功能,例如使用pdftk
(如何在 Ubuntu 18.04 及更高版本中安装 pdftk?):
pdftk in.pdf output out.pdf uncompress
如果sed
您首选的 PDF 阅读器无法读取 的输出,请尝试使用以下方法修复它pdftk
:
pdftk out.pdf output out_pdftk.pdf
进一步阅读:如何编辑 PDF?