使用数字排序合并 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 -v
或sort -n
和pdfunite
的命令可以解决问题,但我不知道如何组合它们。
关于如何将 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? sorryxargs -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 文件的主要内容,如果未能解决你的问题,请参考以下文章