Bien que l'utilisation de find
peut être utile ici, l'interpréteur de commandes fournit lui-même des options permettant de répondre à cette exigence sans avoir recours à des outils tiers. La commande bash
fournit une option de prise en charge étendue des globes qui vous permet d'obtenir les noms de fichiers sous les chemins récursifs qui correspondent aux extensions que vous souhaitez.
L'option étendue est extglob
qui doit être défini à l'aide de la fonction shopt
comme indiqué ci-dessous. Les options sont activées à l'aide de la touche -s
et handicapés avec l'aide de l -u
drapeau. En outre, vous pouvez utiliser quelques options supplémentaires, à savoir nullglob
dans lequel un glob non apparié est entièrement balayé et remplacé par un ensemble de mots nuls. Et globstar
qui permet de parcourir tous les répertoires
shopt -s extglob nullglob globstar
Il ne vous reste plus qu'à formuler l'expression globale pour inclure les fichiers d'une certaine extension, ce que vous pouvez faire comme suit. Nous utilisons un tableau pour remplir les résultats de l'expression globale car, lorsqu'elle est citée correctement et développée, les noms de fichiers contenant des caractères spéciaux restent intacts et ne sont pas interrompus par le découpage des mots effectué par l'interpréteur de commandes.
Par exemple, pour dresser la liste de tous les *.csv
les fichiers dans les chemins récursifs
fileList=(**/*.csv)
L'option **
est de parcourir les sous-dossiers et les *.csv
est une expansion globale permettant d'inclure n'importe quel fichier des extensions mentionnées. Pour imprimer les fichiers, il suffit de faire
printf '%s\n' "${fileList[@]}"
L'utilisation d'un tableau et d'une expansion entre guillemets appropriée est la bonne méthode lorsqu'elle est utilisée dans des scripts de l'interpréteur de commandes, mais pour une utilisation interactive, vous pouvez simplement utiliser ls
avec l'expression globale comme
ls -1 -- **/*.csv
Cela pourrait très bien être étendu pour correspondre à des fichiers multiples, c'est-à-dire des fichiers se terminant par des extensions multiples (similaire à l'ajout de drapeaux multiples dans la fonction find
commande). Prenons par exemple le cas où il faut récupérer tous les fichiers images récursifs, c'est-à-dire d'extension *.gif
, *.png
y *.jpg
Il suffit de
ls -1 -- **/+(*.jpg|*.gif|*.png)
Il pourrait très bien être étendu pour obtenir des résultats négatifs également. Avec la même syntaxe, on pourrait utiliser les résultats du glob pour exclure des fichiers d'un certain type. Supposons que vous vouliez exclure les noms de fichiers avec les extensions ci-dessus, vous pourriez faire
excludeResults=()
excludeResults=(**/!(*.jpg|*.gif|*.png))
printf '%s\n' "${excludeResults[@]}"
La construction !()
est une opération de négation permettant de n'inclure aucune des extensions de fichiers énumérées à l'intérieur et |
est un opérateur d'alternance tel qu'il est utilisé dans la bibliothèque d'expressions régulières étendues pour effectuer une correspondance OR des globes.
Notez que ce support étendu des globes n'est pas disponible dans l'interpréteur de commandes bourne POSIX et qu'il est purement spécifique aux versions récentes de bash
. Ainsi, si vous envisagez la portabilité des scripts fonctionnant sous POSIX et bash
coquilles, cette option ne conviendrait pas.
2 votes
L'erreur provient d'un "{" manquant
0 votes
Cette question est un duplicata de Comment puis-je trouver de manière récursive tous les fichiers dans le dossier courant et les sous-dossiers sur la base d'une correspondance de caractères génériques ?