ZSH
Ich weiß, dass die Frage für Bash markiert wurde; aber nur als Referenz für zsh- Benutzer:
Test auf nicht leeres Verzeichnis
So überprüfen Sie, ob foo
es nicht leer ist:
$ for i in foo(NF) ; do ... ; done
Wenn foo
nicht leer, wird der Code im for
Block ausgeführt.
Test auf leeres Verzeichnis
So überprüfen Sie, ob foo
es leer ist:
$ for i in foo(N/^F) ; do ... ; done
Wenn foo
leer, wird der Code im for
Block ausgeführt.
Anmerkungen
Wir mussten das foo
obige Verzeichnis nicht zitieren , aber wir können dies tun, wenn wir:
$ for i in 'some directory!'(NF) ; do ... ; done
Wir können auch mehr als ein Objekt testen, auch wenn es kein Verzeichnis ist:
$ 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
Alles, was kein Verzeichnis ist, wird einfach ignoriert.
Extras
Da wir globben, können wir jeden Glob (oder jede Klammererweiterung) verwenden:
$ 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
Wir können auch Objekte untersuchen, die in einem Array platziert sind. Mit den Verzeichnissen wie oben zum Beispiel:
$ 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
Auf diese Weise können wir Objekte testen, die möglicherweise bereits in einem Array-Parameter festgelegt sind.
Beachten Sie, dass der Code im for
Block offensichtlich nacheinander in jedem Verzeichnis ausgeführt wird. Wenn dies nicht wünschenswert ist, können Sie einfach einen Array-Parameter auffüllen und dann diesen Parameter bearbeiten:
$ for i in *(NF) ; do full_directories+=($i) ; done
$ do_something $full_directories
Erläuterung
Für zsh-Benutzer gibt es das (F)
Glob-Qualifikationsmerkmal (siehe man zshexpn
), das mit "vollständigen" (nicht leeren) Verzeichnissen übereinstimmt:
$ 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/
Das Qualifikationsmerkmal (F)
listet übereinstimmende Objekte auf: ist ein Verzeichnis UND ist nicht leer. Also, (^F)
stimmt überein: kein Verzeichnis ODER ist leer. So (^F)
würde allein beispielsweise auch reguläre Dateien aufgelistet. Wie auf der zshexp
Manpage erläutert , benötigen wir daher auch das (/)
Glob-Qualifikationsmerkmal, das nur Verzeichnisse auflistet:
$ 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
Um zu überprüfen, ob ein bestimmtes Verzeichnis leer ist, können Sie Folgendes ausführen:
$ mkdir X
$ for i in X(/^F) ; do echo $i ; done ; echo "finished"
X
finished
und nur um sicherzugehen, dass ein nicht leeres Verzeichnis nicht erfasst wird:
$ mkdir Y
$ touch Y/.f
$ for i in Y(/^F) ; do echo $i ; done ; echo "finished"
zsh: no matches found: Y(/^F)
finished
Hoppla! Da Y
zsh nicht leer ist, findet zsh keine Übereinstimmungen für (/^F)
("Verzeichnisse, die leer sind") und gibt daher eine Fehlermeldung aus, dass keine Übereinstimmungen für den Glob gefunden wurden. Wir müssen daher diese möglichen Fehlermeldungen mit dem (N)
Glob-Qualifikationsmerkmal unterdrücken :
$ mkdir Y
$ touch Y/.f
$ for i in Y(N/^F) ; do echo $i ; done ; echo "finished"
finished
Für leere Verzeichnisse benötigen wir daher das Qualifikationsmerkmal (N/^F)
, das Sie wie folgt lesen können: "Warnen Sie mich nicht vor Fehlern, Verzeichnissen, die nicht voll sind".
Ebenso benötigen wir für nicht leere Verzeichnisse das Qualifikationsmerkmal (NF)
, das wir ebenfalls lesen können: "Warnen Sie mich nicht vor Fehlern, vollständige Verzeichnisse".