Boucle à travers tous les fichiers avec une extension spécifique

for i in $(ls);do if [ $i = '*.java' ];then echo "I do something with the file $i" fi done 

Je veux parcourir chaque fichier du dossier en cours et vérifier s’il correspond à une extension spécifique. Le code ci-dessus ne fonctionne pas, savez-vous pourquoi?

Pas de trucs de fantaisie nécessaires:

 for i in *.java; do [ -f "$i" ] || break ... done 

L’agent de sécurité s’assure que s’il n’y a pas de fichiers correspondants, la boucle se ferme sans essayer de traiter un nom de fichier inexistant *.java . Dans bash (ou les shells prenant en charge quelque chose de similaire), vous pouvez utiliser l’option nullglob pour simplement ignorer une correspondance ayant échoué et ne pas entrer dans le corps de la boucle.

 shopt -s nullglob for i in *.java; do ... done 

la bonne réponse est @ chepner

 EXT=java for i in *.${EXT}; do ... done 

Cependant, voici une petite astuce pour vérifier si un nom de fichier a une extension donnée:

 EXT=java for i in *; do if [ "${i}" != "${i%.${EXT}}" ];then echo "I do something with the file $i" fi done 

Ajouter récursivement des sous-dossiers,

 for i in `find . -name "*.java" -type f`; do echo "$i" done 

Comme @chepner le dit dans son commentaire, vous comparez $ i à une chaîne fixe.

Pour développer et rectifier la situation, vous devez utiliser [[]] avec l’opérateur regex = ~

par exemple:

 for i in $(ls);do if [[ $i =~ .*\.java$ ]];then echo "I want to do something with the file $i" fi done 

l’expression rationnelle à droite de = ~ est testée par rapport à la valeur de l’opérateur de gauche et ne doit pas être citée,

mais la réponse de @chepner ci-dessus utilisant glob est un mécanisme beaucoup plus efficace.

Je suis d’accord avec les autres réponses concernant la manière correcte de parcourir les fichiers. Cependant, le PO a demandé:

Le code ci-dessus ne fonctionne pas, savez-vous pourquoi?

Oui!

Un excellent article Quelle est la différence entre test, [et [[?] Explique en détail qu’entre autres différences, vous ne pouvez pas utiliser la expression matching ou pattern matching dans la commande test (qui est un raccourci pour [ )


 Caractéristique nouveau test [[ancien test [exemple

 pattern matching = (ou ==) (non disponible) [[$ name = a *]] ||  echo "nom ne commence pas par 'a': $ name"

 Expression régulière = ~ (non disponible) [[$ (date) = ~ ^ Fri \ ... \ 13]] && echo "C'est le vendredi 13!"
 correspondant à

C’est la raison pour laquelle votre script échoue. Si l’OP est intéressé par une réponse avec la syntaxe [[ qui présente l’inconvénient de ne pas être supporté sur autant de plates-formes que la [ commande], je serais heureux d’éditer ma réponse pour l’inclure.

EDIT: Tout commentaire sur la façon de formater les données dans la réponse sous forme de tableau serait utile!

.img tous les fichiers avec: ( .img , .bin , .txt ) et imprimer le nom du fichier

 for i in *.img *.bin *.txt; do echo "File is: $i" done 

Ou si vous l’aimez récursivement (trouvez aussi dans tous les sous-répertoires):

 for i in `find . -type f -name "*.img" -o -name "*.bin" -o -name "*.txt"`; do echo "File is: $i" done