for i in $(ls);do
if [ $i = '*.java' ];then
echo "I do something with the file $i"
fi
done
Je souhaite parcourir chaque fichier du dossier actuel et vérifier s'il correspond à une extension spécifique. Le code ci-dessus ne fonctionne pas, savez-vous pourquoi?
for i in $(ls *.java); do echo "do something with file $i"; done
?$i
à la chaîne littérale "* .java"; l'expansion du motif n'est pas effectuée ici.if [[ $i == *.java ]]; then
.. (notez les doubles [[]] et les * .java sans guillemets).ls
- accepter la réponse de @ chepnerRéponses:
Aucun truc de fantaisie nécessaire:
Le garde garantit que s'il n'y a pas de fichiers correspondants, la boucle se terminera sans essayer de traiter un nom de fichier inexistant
*.java
. Dansbash
(ou les shells prenant en charge quelque chose de similaire), vous pouvez utiliser l'nullglob
option pour simplement ignorer une correspondance échouée et ne pas entrer dans le corps de la boucle.la source
for i in *.java *.cpp; do
. Si vous avez activé les modèles étendusbash
avecshopt -s extglob
, vous pouvez écrirefor i in *.@(java|cpp); do
.shopt -s nullglob
pour qu'un modèle non correspondant se développe en séquence vide plutôt que d'être traité littéralement.cd
aller dans ce répertoire avant de démarrer lafor
bouclenullglob
pour qu'elle soit traitée comme une séquence vide, oufailglob
pour qu'elle soit traitée comme une erreur. (Si vous définissez les deux,failglob
a priorité.)la bonne réponse est @ chepner
cependant, voici une petite astuce pour vérifier si un nom de fichier a une extension donnée:
la source
ext
au lieu de.java
?Ajouter récursivement des sous-dossiers,
la source
find . -name "*.java" -type f -exec echo \{\} \;
pour éviter une mauvaise analyse de la sortie defind
"$i"
à l'intérieur de la boucle.Boucle à travers tous les fichiers se terminant par:
.img
,.bin
,.txt
suffixe et imprimer le nom du fichier:Ou de manière récursive (à retrouver également dans tous les sous-répertoires):
la source
Je suis d'accord avec les autres réponses concernant la manière correcte de parcourir les fichiers. Cependant, le PO a demandé:
Oui!
Un excellent article Quelle est la différence entre test, [et [[?] Explique en détail que parmi d'autres différences, vous ne pouvez pas utiliser
expression matching
oupattern matching
dans latest
commande (qui est un raccourci pour[
)C'est donc la raison pour laquelle votre script échoue. Si l'OP est intéressé par une réponse avec la
[[
syntaxe (qui a l'inconvénient de ne pas être supportée sur autant de plates-formes que la[
commande), je serais heureux de modifier ma réponse pour l'inclure.EDIT: Toutes les astuces sur la façon de formater les données dans la réponse sous forme de tableau seraient utiles!
la source
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:
l'expression régulière à droite de = ~ est testée par rapport à la valeur de l'opérateur de gauche et ne doit pas être entre guillemets, (les guillemets n'entraîneront pas d'erreur mais se compareront à une chaîne fixe et échoueront donc très probablement "
mais la réponse de @chepner ci-dessus en utilisant glob est un mécanisme beaucoup plus efficace.
la source
ext
au lieu de.java
?if [[ $i == *.java ]]
ouif [[ $i == *.$ext ]]
. But don't parse lsJ'ai trouvé cette solution très pratique. Il utilise l'
-or
option dansfind
:find . -name \*.tex -or -name "*.png" -or -name "*.pdf"
Il trouvera les fichiers avec l' extension
tex
,png
etpdf
.la source