pour les accidents de boucle glob

10

J'essaye de mettre en place un script qui va boucler sur un ensemble de répertoires, et faire une chose quand il trouve des fichiers .jpg, et une autre quand il trouve des fichiers .nef. Le problème est que si un répertoire n'a pas de fichiers .jpg par exemple (ou .nef) alors l'entrée glob n'est plus un glob développé, mais juste une chaîne. Par exemple:

my_dir="pictures/"
ext="JPG"
for f in "$my_dir"*."$ext"; do
    echo $f
done

si le dossier my_dir contient des fichiers .JPG, ils seront répercutés correctement sur la ligne de commande.

pictures/one.JPG
pictures/two.JPG

Cependant, si my_dir n'a pas de fichiers .JPG, alors la boucle entrera pour une itération et un écho:

pictures/*.JPG

comment puis-je construire cela de sorte que si le glob n'a pas de correspondance, il n'entre pas dans la boucle for?

Vince W.
la source

Réponses:

17

C'est un comportement normal et par défaut: si la globalisation ne correspond à aucun fichier / répertoire, le caractère de globalisation d'origine sera conservé.

Si vous souhaitez récupérer un résultat vide à la place, vous pouvez définir l' nullgloboption dans votre script comme suit:

$ shopt -s nullglob
$ for f in "$my_dir"*."$ext"; do echo $f; done
$

Vous pouvez ensuite le désactiver avec:

$ shopt -u nullglob
joepd
la source
6

Un peu de côté, l'utilisation findpeut également être utile ici si la commande que vous exécutez pour les fichiers est assez simple à déposer sur une seule ligne. La recherche peut prendre plusieurs chemins pour rechercher, et trouvera également tous les fichiers dans les sous-répertoires.

$ find foo/ bar/ -name "*.jpg" -exec echo {} \;
foo/ccc.jpg
foo/bbb.jpg
bar/aaa.jpg

(La commande exécutée est donnée après l' -execindicateur, se terminant par ;. {}Est remplacée par le nom du fichier en cours.)

ilkkachu
la source
3

ajoutez cette ligne au début de votre script

shopt -s nullglob
Steve
la source