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


Dans un script bash, comment puis-je 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.


14
2018-05-16 01:15


origine




Réponses:


Si vous voulez toutes les combinaisons possibles, utilisez:

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

ou

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

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

Si vous voulez vraiment juste .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 ne disposez que d'extensions minuscules ou majuscules, il inclura le motif sans correspondance dans la liste des fichiers, entraînant une erreur dans le corps de la boucle. Comme avec nocaseglob, vous voudrez peut-être désactiver l'option shell nullglob par la suite (même si, dans mon expérience, l'utilisation de nullglob est souvent bonne, en particulier dans un script). En fait, je considère plutôt comme une bonne idée d'utiliser la vérification de nocaseglob ou d'existence pour toutes les correspondances de fichiers comme cela, juste au cas où il n'y aurait pas de correspondances.


18
2018-05-16 01:33



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


Vous pourriez également essayer un one-liner tel que

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

ou

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

modifier
Voir aussi le commentaire de @ Yab ci-dessous sur la récursivité.


5
2018-05-16 01:49



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


ls est presque inutile ici, mais pour le disque voici une syntaxe plus proche de votre tentative:

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

Remarques:

  • Je suppose que vous voulez des images à la fois en majuscules et en minuscules. Le séparateur && signifie traiter les fichiers png uniquement si des fichiers PNG existent, 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.

1
2018-05-16 04:17