ZSH
So che la domanda era contrassegnata per bash; ma, solo per riferimento, per gli utenti zsh :
Test per directory non vuota
Per verificare se foo
non è vuoto:
$ for i in foo(NF) ; do ... ; done
dove, se foo
non è vuoto, for
verrà eseguito il codice nel blocco.
Prova per directory vuota
Per verificare se foo
è vuoto:
$ for i in foo(N/^F) ; do ... ; done
dove, se foo
è vuoto, for
verrà eseguito il codice nel blocco.
Appunti
Non abbiamo bisogno di citare la directory foo
sopra, ma possiamo farlo se abbiamo bisogno di:
$ for i in 'some directory!'(NF) ; do ... ; done
Possiamo anche testare più di un oggetto, anche se non è una directory:
$ 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
Tutto ciò che non è una directory verrà semplicemente ignorato.
extra
Dato che stiamo usando globbing, possiamo usare qualsiasi glob (o espansione di parentesi graffe):
$ 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
Possiamo anche esaminare gli oggetti che sono inseriti in un array. Con le directory come sopra, ad esempio:
$ 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
Pertanto, possiamo testare oggetti che potrebbero essere già impostati in un parametro di matrice.
Notare che il codice nel for
blocco viene, ovviamente, eseguito a turno su ogni directory. Se ciò non è desiderabile, puoi semplicemente popolare un parametro di matrice e quindi operare su quel parametro:
$ for i in *(NF) ; do full_directories+=($i) ; done
$ do_something $full_directories
Spiegazione
Per gli utenti zsh c'è il (F)
qualificatore glob (vedi man zshexpn
), che corrisponde alle directory "piene" (non vuote):
$ 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/
Il qualificatore (F)
elenca gli oggetti che corrispondono: è una directory E non è vuota. Quindi, (^F)
corrisponde a: non una directory O è vuota. Quindi, (^F)
da solo , elencerebbe anche file regolari, per esempio. Quindi, come spiegato nella zshexp
pagina man, abbiamo anche bisogno del (/)
qualificatore glob, che elenca solo le directory:
$ 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
Quindi, per verificare se una data directory è vuota, puoi quindi eseguire:
$ mkdir X
$ for i in X(/^F) ; do echo $i ; done ; echo "finished"
X
finished
e solo per essere sicuri che una directory non vuota non venga catturata:
$ mkdir Y
$ touch Y/.f
$ for i in Y(/^F) ; do echo $i ; done ; echo "finished"
zsh: no matches found: Y(/^F)
finished
Oops! Poiché Y
non è vuoto, zsh non trova corrispondenze per (/^F)
("directory vuote") e quindi sputa un messaggio di errore dicendo che non sono state trovate corrispondenze per glob. Dobbiamo quindi sopprimere questi possibili messaggi di errore con il (N)
qualificatore glob:
$ mkdir Y
$ touch Y/.f
$ for i in Y(N/^F) ; do echo $i ; done ; echo "finished"
finished
Quindi, per le directory vuote abbiamo bisogno del qualificatore (N/^F)
, che puoi leggere come: "non avvisarmi di errori, directory che non sono piene".
Allo stesso modo, per directory non vuote abbiamo bisogno del qualificatore (NF)
, che possiamo anche leggere come: "non avvisarmi di errori, directory piene".