ZSH
Je sais que la question a été marquée pour bash; mais, juste pour référence, pour les utilisateurs zsh :
Tester le répertoire non vide
Pour vérifier si ce foo
n'est pas vide:
$ for i in foo(NF) ; do ... ; done
où, si foo
n'est pas vide, le code du for
bloc sera exécuté.
Tester le répertoire vide
Pour vérifier si foo
est vide:
$ for i in foo(N/^F) ; do ... ; done
où, si foo
est vide, le code du for
bloc sera exécuté.
Remarques
Nous n'avons pas eu besoin de citer le répertoire foo
ci-dessus, mais nous pouvons le faire si nous devons:
$ for i in 'some directory!'(NF) ; do ... ; done
Nous pouvons également tester plus d'un objet, même s'il ne s'agit pas d'un répertoire:
$ mkdir X # empty directory
$ touch f # regular file
$ for i in X(N/^F) f(N/^F) ; do echo $i ; done # echo empty directories
X
Tout ce qui n'est pas un répertoire sera simplement ignoré.
Suppléments
Puisque nous sommes en train de globbing, nous pouvons utiliser n'importe quel glob (ou extension d'accolades):
$ mkdir X X1 X2 Y Y1 Y2 Z
$ touch Xf # create regular file
$ touch X1/f # directory X1 is not empty
$ touch Y1/.f # directory Y1 is not empty
$ ls -F # list all objects
X/ X1/ X2/ Xf Y/ Y1/ Y2/ Z/
$ for i in {X,Y}*(N/^F); do printf "$i "; done; echo # print empty directories
X X2 Y Y2
Nous pouvons également examiner les objets placés dans un tableau. Avec les répertoires comme ci-dessus, par exemple:
$ ls -F # list all objects
X/ X1/ X2/ Xf Y/ Y1/ Y2/ Z/
$ arr=(*) # place objects into array "arr"
$ for i in ${^arr}(N/^F); do printf "$i "; done; echo
X X2 Y Y2 Z
Ainsi, nous pouvons tester des objets qui peuvent déjà être définis dans un paramètre de tableau.
Notez que le code dans le for
bloc est, évidemment, exécuté sur chaque répertoire à tour de rôle. Si cela n'est pas souhaitable, vous pouvez simplement renseigner un paramètre de tableau, puis opérer sur ce paramètre:
$ for i in *(NF) ; do full_directories+=($i) ; done
$ do_something $full_directories
Explication
Pour les utilisateurs de zsh, il y a le (F)
qualificatif glob (voir man zshexpn
), qui correspond aux répertoires "pleins" (non vides):
$ mkdir X Y
$ touch Y/.f # Y is now not empty
$ touch f # create a regular file
$ ls -dF * # list everything in the current directory
f X/ Y/
$ ls -dF *(F) # will list only "full" directories
Y/
Le qualificatif (F)
répertorie les objets qui correspondent: est un répertoire ET n'est pas vide. Donc, (^F)
correspond: pas un répertoire OU est vide. Ainsi, (^F)
seul listerait également les fichiers réguliers, par exemple. Ainsi, comme expliqué sur la zshexp
page de manuel, nous avons également besoin du (/)
qualificatif glob, qui répertorie uniquement les répertoires:
$ mkdir X Y Z
$ touch X/f Y/.f # directories X and Y now not empty
$ for i in *(/^F) ; do echo $i ; done
Z
Ainsi, pour vérifier si un répertoire donné est vide, vous pouvez donc lancer:
$ mkdir X
$ for i in X(/^F) ; do echo $i ; done ; echo "finished"
X
finished
et juste pour être sûr qu'un répertoire non vide ne serait pas capturé:
$ mkdir Y
$ touch Y/.f
$ for i in Y(/^F) ; do echo $i ; done ; echo "finished"
zsh: no matches found: Y(/^F)
finished
Oups! Puisqu'il Y
n'est pas vide, zsh ne trouve aucune correspondance pour (/^F)
("répertoires qui sont vides") et crache donc un message d'erreur indiquant qu'aucune correspondance pour le glob n'a été trouvée. Nous devons donc supprimer ces éventuels messages d'erreur avec le (N)
qualificatif glob:
$ mkdir Y
$ touch Y/.f
$ for i in Y(N/^F) ; do echo $i ; done ; echo "finished"
finished
Ainsi, pour les répertoires vides, nous avons besoin du qualificatif (N/^F)
, que vous pouvez lire comme: "ne me prévenez pas des pannes, des répertoires qui ne sont pas pleins".
De même, pour les répertoires non vides, nous avons besoin du qualificatif (NF)
, que nous pouvons également lire comme: "ne me prévenez pas des pannes, répertoires complets".