find(para los predicados -name/ -pathestándar) utiliza patrones comodín al igual que los globos (tenga en cuenta que {a,b}no es un operador de globo; después de la expansión, obtiene dos globos). La principal diferencia es el manejo de barras (y los archivos de puntos y directorios que no se tratan especialmente en find). *en globos no abarcará varios directorios. */*/*hará que se enumeren hasta 2 niveles de directorios. Agregar un -path './*/*/*'archivo coincidirá con cualquier archivo que tenga al menos 3 niveles de profundidad y no dejará findde enumerar el contenido de ningún directorio a ninguna profundidad.
Para ese particular
./foo*bar/quux[A-Z]{.bak,}/pic[0-9][0-9][0-9][0-9]?.jpg
un par de globos, es fácil de traducir, quieres directorios en profundidad 3, por lo que puedes 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 {} +
(o -depth 3con algunas findimplementaciones). O POSIXY:
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 {} +
Lo que garantizaría que esos *y ?no podían coincidir con los /personajes
( find, a diferencia de los globos, leería el contenido de directorios distintos de foo*barlos del directorio actual¹, y no ordenaría la lista de archivos. Pero si dejamos de lado el problema de que lo que coincide [A-Z]o el comportamiento de */ ?con respecto a los caracteres no válidos es sin especificar, obtendría la misma lista de archivos).
Pero en cualquier caso, como ha demostrado @muru , no hay necesidad de recurrir findsi es solo para dividir la lista de archivos en varias ejecuciones para evitar el límite de la execve()llamada del sistema. Algunos proyectiles como zsh(con zargs) o ksh93(con command -x) incluso tienen soporte incorporado para eso.
Con zsh(cuyos globos también tienen el equivalente -type fy la mayoría de los otros findpredicados), por ejemplo:
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)es un operador glob contrario a {,.bak}, el (.)calificador glob es el equivalente de find's -type f, agregue oNallí para omitir la clasificación como con find, Dpara incluir archivos de puntos (no se aplica a este glob))
¹ Para findrastrear el árbol de directorios como lo harían los globos, necesitarías 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 \) \)
Es decir, pode todos los directorios en el nivel 1 excepto foo*barlos y todos en el nivel 2 excepto los quux[A-Z]o quux[A-Z].bak, y luego seleccione pic...los del nivel 3 (y pode todos los directorios en ese nivel).
-patho-ipath.find . -path './foo*bar/quux[A-Z]/pic[0-9][0-9][0-9][0-9]?.jpg'debería funcionar, excepto que coincidirá/fooz/blah/bar/quuxA/pic1234d.jpg. será eso un problema?