Ok, você quer executar um comando em cada diretório em uma árvore de diretório - o diretório atual, seus subdiretórios, seus subdiretórios, etc. A primeira coisa a fazer é enumerar os diretórios em questão. Com o comando find
, diga para listar apenas os diretórios:
find . -type d
O comando que você deseja executar em cada diretório é
gmic ./*jpg -gimp_montage 4,\""V(H(0,1),H(2,V(3,4)))"\",1,1.0,0,5,0,0,0,255,0,0,0,0 -o -0000."$(date)".jpg
Este é um comando shell, contendo uma expansão curinga e uma substituição de comando. Você precisa executar um shell para executá-lo. Como esse shell será informado sobre o que fazer por find
, não será o shell em que você está executando find
in: é necessário informar find
para executar um shell. Passe o diretório onde você quer agir como um argumento para o shell.
find . -type d -exec sh -c '…' {} \;
Antes de poder chamar o gmic
, você precisa fazer algumas coisas nesse script: altere para o diretório em questão e verifique se ele contém .jpg
arquivos.
find . -type d -exec sh -c '
cd "$0" || exit
set -- *.jpg
if [ -e "$1" ]; then
gmic "$@" -gimp_montage 4,\""V(H(0,1),H(2,V(3,4)))"\",1,1.0,0,5,0,0,0,255,0,0,0,0 -o -0000."$(date)".jpg
fi
' {} \;
Como alternativa, você pode dizer a find
para listar .jpg
arquivos. No entanto, isso dificulta a execução do comando apenas um por diretório.
Se o seu shell for bash, ao contrário de sh
simples, você pode usar seu curinga **
para recorrer aos diretórios. Isso é mais fácil do que usar find
. No bash ≤4.2, cuidado com o fato de **
atravessar o link simbólico para os diretórios. Você pode simplificar um pouco o teste de existência de arquivos.
shopt -s globstar nullglob
for dir in ./**/*/; do
files=("$dir/"*.jpg)
if [[ ${#files[@]} -ne 0 ]]; then
gmic "${files[@]}" -gimp_montage 4,\""V(H(0,1),H(2,V(3,4)))"\",1,1.0,0,5,0,0,0,255,0,0,0,0 -o "$dir/-0000.$(date)".jpg
fi
done
No zsh, você pode usar um modificador de histórico em um qualificador de glob para enumerar os diretórios que contêm .jpg
arquivos e, em seguida, filtrar a matriz resultante para manter uma única cópia de cada diretório .
dirs=(./**/*.jpg(:h))
for dir in ${(u)dirs}; do
gmic $dir/*.jpg -gimp_montage 4,\""V(H(0,1),H(2,V(3,4)))"\",1,1.0,0,5,0,0,0,255,0,0,0,0 -o "$dir/-0000.$(date).jpg"
done
(Aside: -0000.Sat Mar 14 15:51:28 CET 2015.jpg
é um nome muito estranho para um arquivo. Arquivos cujo nome começa com -
tendem a causar problemas porque se parecem com opções de comandos. Datas são mais convenientes para manipular em um formato onde ordenar lexicograficamente é idêntico a ordenar cronologicamente, como 20150314-145128
.)