Risposte:
È possibile specificare una barra alla fine per abbinare solo le directory:
for d in */ ; do
echo "$d"
done
[[ -L $d ]]se $ d è un collegamento simbolico.
set -Pinfluisce solo sui comandi che cambiano directory. sprunge.us/TNac
[[ -L "$f" ]]in questo caso non escluderemo i collegamenti simbolici con */, devi eliminare la barra finale [[ -L "${f%/}" ]](vedi Test per il collegamento con barra finale )
Puoi provare con -d:
for f in *; do
if [ -d "$f" ]; then
# $f is a directory
fi
done
Questo è uno degli operatori di test dei file .
if [[ -d "$f" && ! -L "$f" ]]escluderà i
if [[ "$f" = "*" ]]; then continue; fi
Attenzione che la soluzione di choroba, sebbene elegante, può suscitare comportamenti imprevisti se non ci sono directory disponibili nella directory corrente. In questo stato, anziché saltare il forciclo, bash eseguirà il ciclo esattamente una volta dove dè uguale a */:
#!/usr/bin/env bash
for d in */; do
# Will print */ if no directories are available
echo $d
done
Ti consiglio di utilizzare quanto segue per proteggere da questo caso:
#!/usr/bin/env bash
for f in *; do
if [ -d ${f} ]; then
# Will not run if no directories are available
echo $f
fi
done
Questo codice eseguirà il ciclo attraverso tutti i file nella directory corrente, verificando se si ftratta di una directory, quindi echo fse la condizione ritorna vera. Se fè uguale a */, echo $fnon verrà eseguito.
shopt -s nullglob.
Se è necessario selezionare file più specifici di quelli utilizzati solo dalle directory finde passarli a while read:
shopt -s dotglob
find * -prune -type d | while IFS= read -r d; do
echo "$d"
done
Utilizzare shopt -u dotglobper escludere directory nascoste (o setopt dotglob/ unsetopt dotglobin zsh).
IFS=per evitare la divisione di nomi di file contenenti uno dei $IFS, ad esempio:'a b'
vedi AsymLabs risposta sotto per ulteriori findopzioni
modifica:
Nel caso in cui sia necessario creare un valore di uscita all'interno del ciclo while, è possibile aggirare la subshell aggiuntiva con questo trucco:
while IFS= read -r d; do
if [ "$d" == "something" ]; then exit 1; fi
done < <(find * -prune -type d)
Puoi usare pure bash per questo, ma è meglio usare find:
find . -maxdepth 1 -type d -exec echo {} \;
(trova inoltre includerà directory nascoste)
shopt -s dotglobper bashincludere directory nascoste. Il tuo includerà anche .. Si noti inoltre che -maxdepthnon è un'opzione standard ( -pruneè).
dotglobopzione è interessante ma dotglobsi applica solo all'uso di *. find .includerà sempre le directory nascoste (e anche la directory corrente)
Questo viene fatto per trovare sia le directory visibili che quelle nascoste nella presente directory di lavoro, esclusa la directory principale:
per scorrere semplicemente le directory:
find -path './*' -prune -type d
per includere collegamenti simbolici nel risultato:
find -L -path './*' -prune -type d
fare qualcosa per ogni directory (esclusi i collegamenti simbolici):
find -path './*' -prune -type d -print0 | xargs -0 <cmds>
per escludere directory nascoste:
find -path './[^.]*' -prune -type d
per eseguire più comandi sui valori restituiti (un esempio molto inventato):
find -path './[^.]*' -prune -type d -print0 | xargs -0 -I '{}' sh -c \
"printf 'first: %-40s' '{}'; printf 'second: %s\n' '{}'"
invece di 'sh -c' può anche usare 'bash -c', ecc.
... -print0 | xargs -0 ...se non sai quali sono i nomi esatti.
find * | while read file; do ...
Puoi scorrere tutte le directory incluse le directory nascoste (che iniziano con un punto) in una riga e più comandi con:
for file in */ .*/ ; do echo "$file is a directory"; done
Se si desidera escludere i collegamenti simbolici:
for file in *; do
if [[ -d "$file" && ! -L "$file" ]]; then
echo "$file is a directory";
fi;
done
nota: l' uso dell'elenco */ .*/funziona in bash, ma mostra anche le cartelle .e ..mentre in zsh non le mostrerà ma genererà un errore se non ci sono file nascosti nella cartella
Una versione più pulita che includerà directory nascoste ed escluderà ../ sarà con l'opzione dotglob:
shopt -s dotglob
for file in */ ; do echo "$file is a directory"; done
(o setopt dotglobin zsh)
puoi deselezionare dotglob con
shopt -u dotglob
Ciò includerà il percorso completo in ciascuna directory nell'elenco:
for i in $(find $PWD -maxdepth 1 -type d); do echo $i; done
Utilizzare findcon -execper scorrere ciclicamente le directory e chiamare una funzione nell'opzione exec:
dosomething () {
echo "doing something with $1"
}
export -f dosomething
find -path './*' -prune -type d -exec bash -c 'dosomething "$0"' {} \;
Utilizzare shopt -s dotglobo shopt -u dotglobper includere / escludere directory nascoste
ls -l | grep ^d
o:
ll | grep ^d
Puoi impostarlo come alias
lsrisposta basata su, che elenca le directory.
ls: mywiki.wooledge.org/ParsingLs