find (para os predicados padrão -name / -path ) usa padrões curinga assim como globs (observe que {a,b} não é um operador glob; após a expansão, você obtém dois globs). A principal diferença é o tratamento de barras (e os arquivos de ponto e diretórios não sendo tratados especialmente em find ). * em globs não abrangerá vários diretórios. */*/* fará com que até 2 níveis de diretórios sejam listados. Adicionar -path './*/*/*' corresponderá a todos os arquivos com pelo menos 3 níveis de profundidade e não impedirá que find liste o conteúdo de qualquer diretório em qualquer profundidade.
Para esse particular
./foo*bar/quux[A-Z]{.bak,}/pic[0-9][0-9][0-9][0-9]?.jpg
Par de globs, é fácil de traduzir, você está querendo diretórios na profundidade 3, então você pode usar:
find . -mindepth 3 -maxdepth 3 \
\( -path './foo*bar/quux[A-Z].bak/pic[0-9][0-9][0-9][0-9]?.jpg' -o \
-path './foo*bar/quux[A-Z]/pic[0-9][0-9][0-9][0-9]?.jpg' \) \
-exec cmd {} +
(ou -depth 3 com algumas implementações find ). Ou POSIXly:
find . -path './*/*/*' -prune \
\( -path './foo*bar/quux[A-Z].bak/pic[0-9][0-9][0-9][0-9]?.jpg' -o \
-path './foo*bar/quux[A-Z]/pic[0-9][0-9][0-9][0-9]?.jpg' \) \
-exec cmd {} +
O que garantiria que os * e ? não poderiam corresponder a / caracteres.
( find , ao contrário de globs, leria o conteúdo de diretórios diferentes de foo*bar no diretório atual¹, e não ordenaria a lista de arquivos. Mas se deixarmos de lado o problema de que o que é correspondido por [A-Z] ou o comportamento de * / ? em relação a caracteres inválidos não é especificado, você obterá a mesma lista de arquivos).
Mas, em qualquer caso, como @muru mostrou , não é necessário recorrer a find se for apenas dividir a lista de arquivos em várias execuções para contornar o limite da chamada do sistema execve() . Alguns shells como zsh (com zargs ) ou ksh93 (com command -x ) ainda têm suporte embutido para isso.
Com zsh (cujas globs também têm o equivalente a -type f e a maioria dos outros find predicados), por exemplo:
autoload zargs # if not already in ~/.zshrc
zargs ./foo*bar/quux[A-Z](|.bak)/pic[0-9][0-9][0-9][0-9]?.jpg(.) -- cmd
( (|.bak) é um operador glob ao contrário de {,.bak} , o qualificador (.) glob é o equivalente de find ' -type f , adicione oN lá para ignorar a classificação como find , D para incluir arquivos de pontos (não se aplica a este glob))
¹ Para find rastrear a árvore de diretórios, como acontece com globs, você precisa de algo como:
find . ! -name . \( \
\( -path './*/*' -o -name 'foo*bar' -o -prune \) \
-path './*/*/*' -prune -name 'pic[0-9][0-9][0-9][0-9]?.jpg' -exec cmd {} + -o \
\( ! -path './*/*' -o -name 'quux[A-Z]' -o -name 'quux[A-Z].bak' -o -prune \) \)
Isso é podar todos os diretórios no nível 1, exceto os foo*bar e todos no nível 2, exceto os quux[A-Z] ou quux[A-Z].bak e, em seguida, selecionar pic... em nível 3 (e podar todos os diretórios a esse nível).