Я использую следующий скрипт для пакетного комбинирования последовательностей изображений, расположенных внутри подкаталогов, в .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.
И так далее и т. Д. Для каждого каталога, содержащего изображения.
Проблема заключается в том, что если вы столкнулись с каталогом без подходящих файлов изображений, glob передается без изменений в команду convert, поэтому вы пытаетесь преобразовать файлы с буквальным именем ./*jpg, ./*png и т. д. [ ! d0]
Обычным решением для этого (в bash и других оболочках, которые его поддерживают) является включение нулевого глобуса. К сожалению, в этом случае просто создается другая ошибка, так как теперь вы вызываете convert без каких-либо входных файлов.
Я не могу придумать более элегантный способ справиться с этим, кроме настройки nullglob, расширяя globs в массиве, а затем явно проверяя, является ли массив пустым или нет. Так, например:
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
Ошибки вызваны отсутствием соответствующих файлов. Но не анализируйте вывод 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
Проблема заключается в том, что если вы столкнулись с каталогом без подходящих файлов изображений, glob передается без изменений в команду convert, поэтому вы пытаетесь преобразовать файлы с буквальным именем ./*jpg, ./*png и т. д. [ ! d0]
Обычным решением для этого (в bash и других оболочках, которые его поддерживают) является включение нулевого глобуса. К сожалению, в этом случае просто создается другая ошибка, так как теперь вы вызываете convert без каких-либо входных файлов.
Я не могу придумать более элегантный способ справиться с этим, кроме настройки nullglob, расширяя globs в массиве, а затем явно проверяя, является ли массив пустым или нет. Так, например:
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
Ошибки вызваны отсутствием соответствующих файлов. Но не анализируйте вывод 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