我使用以下脚本将位于子目录中的图像序列批量合并到 .pdf 文件中。它运行良好,但在操作时会打印错误。我有兴趣改进脚本以消除错误。
#!/bin/bash
for i in $(find . -type d)
do
convert "${i}/*jpg" "${i}/*png" "${i}/*tif" "${i}/*tiff" "${i}.pdf"
done
下面是错误的示例..
convert: unable to open image `./*jpg': No such file or directory @ error/blob.c/OpenBlob/2712.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.
convert: unable to open image `./*png': No such file or directory @ error/blob.c/OpenBlob/2712.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.
convert: unable to open image `./*tif': No such file or directory @ error/blob.c/OpenBlob/2712.
对于每个包含图像的目录,依此类推。
答案1
问题是,如果您遇到没有匹配图像文件的目录,则 glob 会以未扩展的形式传递给 convert 命令,因此您最终会尝试转换具有文字名称的文件./*jpg
,./*png
依此类推。
对此的通常解决方案(在 bash 和其他支持它的 shell 中)是启用空值通配符。不幸的是,在这种情况下,这只会产生不同的错误,因为现在您在调用时convert
根本没有任何输入文件。
除了设置、扩展数组中的 glob,然后明确测试数组是否为空之外,我想不出更优雅的方法来处理这个问题nullglob
。例如:
find $PWD -type d -execdir bash -c '
shopt -s nullglob
files=("$1"/*.jpg "$1"/*.png)
if (( ${#files[@]} == 0 )); then
echo "$1: nothing to do here"
else
convert "${files[@]}" "$1.pdf"
fi' bash {} \;
或者更紧凑
find $PWD -type d -execdir bash -c '
shopt -s nullglob
files=("$1"/*.jpg "$1"/*.png)
(( ${#files[@]} == 0 )) || convert "${files[@]}" "$1.pdf"
' bash {} \;
或者,按照@Zanna 的做法,彻底废除find
:
#!/bin/bash
shopt -s globstar
shopt -s nullglob
for f in **/*; do
[[ -d "$f" ]] || continue
files=( "$f"/*.jpg "$f"/*.png )
(( ${#files[@]} != 0 )) || continue
convert "${files[@]}" "$f.pdf"
done
答案2
错误是由于缺少匹配的文件而导致的。但不要解析输出find
- 而是使用 globstar 和测试。
shopt -s globstar
for i in **; do
[[ -d "$i" ]] &&
convert "$i"/*jpg "$i"/*png "$i"/*tif "$i"/*tiff "$i".pdf 2>/dev/null
done
shopt -u globstar