find(pour les prédicats -name/ -pathstandard) utilise des modèles génériques comme les globs (notez que ce {a,b}n'est pas un opérateur glob; après expansion, vous obtenez deux globs). La principale différence réside dans la gestion des barres obliques (et des fichiers de points et des répertoires qui ne sont pas traités spécialement dans find). *dans globs ne s'étendra pas sur plusieurs répertoires. */*/*entraînera la liste de 2 niveaux de répertoires. L'ajout d'un -path './*/*/*'correspondra à tous les fichiers qui ont au moins 3 niveaux de profondeur et ne s'arrêtera pas findde lister le contenu d'un répertoire à n'importe quelle profondeur.
Pour ce particulier
./foo*bar/quux[A-Z]{.bak,}/pic[0-9][0-9][0-9][0-9]?.jpg
quelques globes, c'est facile à traduire, vous voulez des répertoires en profondeur 3, donc vous pouvez utiliser:
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 3avec certaines findimplémentations). Ou POSIX:
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 {} +
Ce qui garantirait que ceux-ci *et ?ne pourraient pas correspondre aux /caractères.
( find, contrairement à globs lirait le contenu de répertoires autres que foo*barceux du répertoire courant¹, et ne trierait pas la liste des fichiers. Mais si nous laissons de côté le problème de ce à quoi correspond [A-Z]ou le comportement de */ ?en ce qui concerne les caractères invalides non spécifié, vous obtiendrez la même liste de fichiers).
Mais dans tous les cas, comme l' a montré @muru , il n'est pas nécessaire d'y recourir finds'il s'agit simplement de diviser la liste de fichiers en plusieurs exécutions pour contourner la limite de l' execve()appel système. Certains shells comme zsh(avec zargs) ou ksh93(avec command -x) ont même un support intégré pour cela.
Avec zsh(dont les globes ont également l'équivalent de -type fet la plupart des autres findprédicats), par exemple:
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)est un opérateur glob contrairement à {,.bak}, le (.)qualificatif glob est l'équivalent de find's' -type f, ajoutez- oNy pour ignorer le tri comme avec find, Dpour inclure les fichiers de points (ne s'applique pas à ce glob))
¹ Pour findexplorer l'arborescence de répertoires comme le feraient les globes, vous auriez besoin de quelque chose comme:
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 \) \)
C'est-à-dire élaguer tous les répertoires au niveau 1 à l'exception de foo*barceux et tous au niveau 2 à l'exception de ceux quux[A-Z]ou quux[A-Z].bak, puis sélectionner pic...ceux au niveau 3 (et élaguer tous les répertoires à ce niveau).
-pathou-ipath.find . -path './foo*bar/quux[A-Z]/pic[0-9][0-9][0-9][0-9]?.jpg'devrait fonctionner - sauf qu'il correspondra/fooz/blah/bar/quuxA/pic1234d.jpg. Sera-ce un problème?