Bash shell: liste tous les fichiers de type .png ou .PNG?

14

Dans un script bash, comment dire "pour tous les fichiers de type .png ou .PNG"?

J'essaie :

for i in (`ls *.PNG` && `ls *.png`)

mais obtenir une erreur de syntaxe.

Simon
la source

Réponses:

18

Si vous souhaitez toutes les combinaisons possibles, utilisez:

for i in *.[Pp][Nn][Gg]; do

ou

shopt -s nocaseglob
for i in *.png; do

bien que celui-ci rendra tous les globes shell de votre script (c'est-à-dire les correspondances de fichiers génériques) insensibles à la casse jusqu'à ce que vous exécutiez shopt -u nocaseglob.

Si vous voulez vraiment seulement .PNG et .png (et pas, par exemple, .PnG ou .pnG), alors utilisez soit

shopt -s nullglob
for i in *.png *.PNG; do

ou

for i in *.png *.PNG; do
    [[ -e "$i" ]] || continue

... la raison de la vérification nullglob ou de l'existence est que si vous n'avez que des extensions minuscules ou majuscules, cela inclura le modèle sans correspondance dans la liste des fichiers, conduisant à une erreur dans le corps de la boucle. Comme avec nocaseglob, vous voudrez peut-être désactiver l'option shell nullglob par la suite (bien que dans mon expérience, avoir nullglob activé est souvent bon, surtout dans un script). En fait, je considère plutôt comme une bonne idée d'utiliser soit le nocaseglob soit le contrôle d'existence pour toutes les correspondances de fichiers comme ceci, juste au cas où il n'y en aurait pas.

Gordon Davisson
la source
5
for i in *.{png,PNG}
glenn jackman
@glenn: Cela fonctionnerait aussi (équivalent à `* .png * .PNG), bien que vous ayez toujours besoin de nullglob ou du contrôle d'existence.
Gordon Davisson
5

Vous pouvez également essayer une doublure comme

trouver . -iname "* .png" -exec ....

ou

trouver . -iname "* .png" | xargs ....

Modifier
Voir également le commentaire de @ Yab ci-dessous sur la récursivité.

Alain Pannetier
la source
1
find est cependant récursif par défaut, donc pour obtenir le même résultat que la question vous demande, vous devriez le faire find -maxdepth 1 -iname "*.png"
Yab
@Yab, vous avez parfaitement raison. J'ai négligé cet aspect.
Alain Pannetier
1

ls est presque inutile ici, mais pour mémoire, voici une syntaxe plus proche de votre tentative:

for i in $(ls *.PNG ; ls *.png)

Remarques:

  • Je suppose que vous voulez des images en majuscules et en minuscules. Le séparateur && signifierait traiter les fichiers png uniquement s'il existe des fichiers PNG, ce qui n'a probablement pas beaucoup de sens.
  • vous aurez des messages d'erreur affichés si aucun fichier n'est trouvé avec l'un ou l'autre modèle.
jlliagre
la source