使用数字排序合并 pdf 文件

Posted

技术标签:

【中文标题】使用数字排序合并 pdf 文件【英文标题】:Merge pdf files with numerical sort 【发布时间】:2014-07-01 20:05:05 【问题描述】:

我正在尝试编写一个 bash 脚本来将一个目录的所有 pdf 文件合并到一个 pdf 文件中。命令pdfunite *.pdf output.pdf 成功实现了这一点,但它以常规顺序合并输入文档:

1.pdf
10.pdf
11.pdf
2.pdf
3.pdf
4.pdf
5.pdf
6.pdf
7.pdf
8.pdf
9.pdf

虽然我希望按数字顺序合并文档:

1.pdf
2.pdf
3.pdf
4.pdf
5.pdf
6.pdf
7.pdf
8.pdf
9.pdf
10.pdf
11.pdf

我猜想混合ls -vsort -npdfunite 的命令可以解决问题,但我不知道如何组合它们。 关于如何将 pdf 文件与数字排序合并的任何想法?

【问题讨论】:

【参考方案1】:

您可以使用$() 嵌入命令结果, 所以你可以做以下

$ pdfunite $(ls -v *.pdf) output.pdf

$ pdfunite $(ls *.pdf | sort -n) output.pdf

但是,请注意,当文件名包含空格等特殊字符时,这不起作用。

在这种情况下,您可以执行以下操作:

ls -v *.txt | bash -c 'IFS=$'"'"'\n'"'"' read -d "" -ra x;pdfunite "$x[@]" output.pdf'

虽然看起来有点复杂,其实只是结合

Bash: Read tab-separated file line into array build argument lists containing whitespace How to escape single-quotes within single-quoted strings?

请注意,您不能使用xargs,因为pdfunite 需要输入pdf 作为参数的中间。 我避免使用 readarray,因为旧 bash 版本不支持它,但如果你有更新的 bash,你可以使用它来代替 IFS=.. read -ra ..

【讨论】:

非常感谢!我确认解决方案 1 和 2 工作,但我无法让解决方案 3 (xargs) 工作。我认为 pdfunite 没有识别输入。您能否详细解释一下您的解决方案 3? sorry xargs -I 只能一个一个应用参数。算了,我会写新的答案。 是的,那个答案其实有点错误(第二个sh字符串是垃圾),所以我更新了答案并写了正确的 再次抱歉,我是傻瓜。我忘记排序了。 find 无法排序。我会再次更新答案。 终于似乎得到了一个可行的答案。希望这将是最终版本。【参考方案2】:

分多个步骤进行。我假设你有从 1 到 99 的文件。

 pdfunite $(find ./ -regex ".*[^0-9][0-9][^0-9].*"  | sort) out1.pdf
 pdfunite out1.pdf $(find ./ -regex ".*[^0-9]1[0-9][^0-9].*"  | sort) out2.pdf
 pdfunite out2.pdf $(find ./ -regex ".*[^0-9]2[0-9][^0-9].*"  | sort) out3.pdf

等等。

最终文件将按数字顺序包含所有 pdf。

!!! 谨防写入 out1.pdf 等输出文件,否则 pdfunite 将覆盖最后一个文件 !!!

编辑: 抱歉,我在每个正则表达式中都遗漏了 [^0-9]。在上面的命令中更正了它。

【讨论】:

感谢您的提示,但排序不正确。如果合并1.pdf, 2.pdf, 11.pdf,则顺序为11.pdf, 1.pdf, 2.pdf。将sort 更改为sort -n 并不能解决问题 谢谢,我更正了答案。另外,想说的是上面的命令不是通用的,但涵盖了大部分人类类型的文件。 感谢您的更正,但它还不起作用。 pdfunite $(find ./ -regex ".*[^0-9][0-9][^0-9].*" | sort) out1.pdf 生成 out1.pdf 仅包括 1.pdf 和 2.pdf(不是 11.pdf) 您还必须遵循其他命令。运行下一行,你会得到 11.pdf。如果你仔细看,第二行的输入是out1.pdf,输出是out2.pdf。甚至正则表达式也略有不同。【参考方案3】:

您可以重命名您的文档,例如 001.pdf 002.pdf 等等。

【讨论】:

【参考方案4】:
destfile=combined.pdf
find . -maxdepth 1 -type f -name '*.pdf' -print0 \
   | sort -z -t '/' -k2n \
   |  cat; printf '%s\0' "$destfile";  \
   | xargs -0 -x pdfunite
    变量 destfile 保存目标 pdf 文件的名称。 find 命令查找当前目录下的所有 pdf 文件,并将它们输出为 NUL 分隔列表。 sort 命令读取 NUL 分隔的文件名列表。它指定/ 的字段分隔符。它按数字的第二个字段排序。 (回想一下find 的输出看起来像./11.pdf ...。) 我们在发送到 xargs 之前附加 destfile,确保以 NUL 结束。 xargs 读取 NUL 分隔的 args 并将它们提供给 pdfunite 命令。我们提供了-x 选项,以便在命令长度过长时xargs 将退出。我们不希望xargs 执行部分构造的命令。

此解决方案处理带有嵌入换行符和空格的文件名。

【讨论】:

以上是关于使用数字排序合并 pdf 文件的主要内容,如果未能解决你的问题,请参考以下文章

[pdf文件合并]怎么把多个pdf文件合并成一个?你值得拥有这个PDF合并工具

如何使用php合并两个pdf文件

使用Python批量合并PDF文件(带书签功能)

如何将两个pdf文件合并成一个

使用 PHP 合并 PDF 文件 [关闭]

如何使用 php mpdf 库将多个 PDF 文件合并为一个 PDF