我想将一些文件从 jpeg 转换为 pdf。我正在使用以下命令。
$ convert image1.jpg image1.pdf
但我有 100 张图像。我应该如何将它们全部转换为相应的pdf?
我试过
$ convert image*.jpg image*.pdf
这不起作用。
答案1
在bash中:
for f in *.jpg; do
convert ./"$f" ./"${f%.jpg}.pdf"
done
答案2
您可以使用mogrify
为此的命令。通常,它会就地修改文件,但在转换格式时,它会写入一个新文件(只需更改扩展名以匹配新格式)。因此:
mogrify -format pdf -- *.jpg
(与 enzotib 一样./*.jpg
, 可以--
防止任何奇怪的文件名被解释为开关。大多数命令都认为--
意思是“此时停止寻找选项”。)
答案3
更快但不寻常的语法:
parallel convert '{} {.}.pdf' ::: *.jpg
并行运行(使用https://www.gnu.org/software/parallel/)。我还没有注意到任何多线程convert
,这会限制有效的并行化。如果您担心这一点,请参阅下面的评论,了解确保不会发生多线程的方法。
答案4
下面是一种将上述建议中的最佳内容结合到一个简单、高效、健壮的命令行中的方法:
find /path/to/files -iname '*.jpg' -exec mogrify -format pdf {} +
它适用于以 a 开头-
或包含空格的文件名。请注意其中的使用-iname
是不区分大小写的版本,所以它也-name
可以在..JPG
.jpg
这用于find
获取文件列表,而不是使用通配符进行 shell 通配符*.jpg
,这可能会导致“参数列表太长”错误在某些系统上。尽管正如 @enzotib 在评论中指出的那样,使用的行为for 循环中的通配符与命令参数的通配符不同。
另外,find
将处理子目录,而 shell 通配符不会处理子目录,除非您碰巧具有特定于 shell 的功能,例如**/*jpg
zsh 中的递归通配符语法。
编辑:我想我会添加另一个有用的功能,find
这是我在阅读评论后想到的@IlmariKaronen关于重新运行命令并仅转换自第一次运行以来已更改的文件。
在第一遍中,您可以touch
在转换完成后获取时间戳文件。
find /path/to/files -iname '*.jpg' -exec mogrify -format pdf {} +; touch timestamp
然后添加-newer timestamp
到find
表达式以对上次修改时间比时间戳文件新的文件子集进行操作。每次运行后继续更新时间戳文件。
find /path/to/files -iname '*.jpg' -newer timestamp -exec mogrify -format pdf {} +; touch timestamp
这是一种避免求助于 Makefile 的简单方法(除非您已经在使用 Makefile),这也是为什么它值得find
尽可能使用的另一个很好的原因……它具有多种表达能力,同时保持简洁。