Antworten:
Sie können einen Schrägstrich am Ende angeben, um nur Verzeichnisse zu finden:
for d in */ ; do
echo "$d"
done
[[ -L $d ]]ob $ d ein symbolischer Link ist.
set -Pbetrifft nur Befehle, die das Verzeichnis wechseln. sprunge.us/TNac
[[ -L "$f" ]]Symlinks werden in diesem Fall nicht mit ausgeschlossen */, Sie müssen den abschließenden Schrägstrich mit [[ -L "${f%/}" ]]
Sie können testen mit -d:
for f in *; do
if [ -d "$f" ]; then
# $f is a directory
fi
done
Dies ist einer der Dateitestoperatoren .
if [[ -d "$f" && ! -L "$f" ]]schließt
if [[ "$f" = "*" ]]; then continue; fi
Beachten Sie, dass die elegante Lösung von choroba unerwartetes Verhalten hervorrufen kann, wenn im aktuellen Verzeichnis keine Verzeichnisse verfügbar sind. In diesem Zustand wird die forSchleife nicht übersprungen, sondern genau einmal ausgeführt, wobei dgilt */:
#!/usr/bin/env bash
for d in */; do
# Will print */ if no directories are available
echo $d
done
Ich empfehle Folgendes, um sich vor diesem Fall zu schützen:
#!/usr/bin/env bash
for f in *; do
if [ -d ${f} ]; then
# Will not run if no directories are available
echo $f
fi
done
Dieser Code durchläuft alle Dateien im aktuellen Verzeichnis, überprüft, ob fes sich um ein Verzeichnis handelt, und gibt ein Echo aus, fwenn die Bedingung wahr ist. Wenn fgleich */, echo $fwird nicht ausgeführt.
shopt -s nullglob.
Wenn Sie spezifischere Dateien als nur Verzeichnisse auswählen müssen, verwenden Sie diese findund übergeben Sie sie an while read:
shopt -s dotglob
find * -prune -type d | while IFS= read -r d; do
echo "$d"
done
Verwenden Sie shopt -u dotglobdiese Option, um versteckte Verzeichnisse (oder setopt dotglob/ unsetopt dotglobin zsh) auszuschließen .
IFS=Um zu vermeiden, dass Dateinamen aufgeteilt werden, die eine der folgenden Angaben enthalten $IFS:'a b'
siehe AsymLabs beantworten unten für weitere findOptionen
edit:
Falls Sie einen Exit-Wert innerhalb der while-Schleife erstellen müssen, können Sie die zusätzliche Subshell mit folgendem Trick umgehen:
while IFS= read -r d; do
if [ "$d" == "something" ]; then exit 1; fi
done < <(find * -prune -type d)
Sie können dafür reines bash verwenden, aber es ist besser, find zu verwenden:
find . -maxdepth 1 -type d -exec echo {} \;
(find schließt zusätzlich versteckte Verzeichnisse ein)
shopt -s dotglobfor verwenden bash, um versteckte Verzeichnisse einzuschließen. Ihr wird auch enthalten .. Beachten Sie auch, dass dies -maxdepthkeine Standardoption -pruneist.
dotglobOption ist interessant, dotglobgilt aber nur für die Verwendung von *. find .wird immer versteckte Verzeichnisse (und das aktuelle Verzeichnis auch) enthalten
Dies geschieht, um sowohl sichtbare als auch versteckte Verzeichnisse im aktuellen Arbeitsverzeichnis zu finden, mit Ausnahme des Stammverzeichnisses:
So durchlaufen Sie Verzeichnisse:
find -path './*' -prune -type d
Symlinks in das Ergebnis aufnehmen:
find -L -path './*' -prune -type d
Um etwas mit jedem Verzeichnis zu tun (außer Symlinks):
find -path './*' -prune -type d -print0 | xargs -0 <cmds>
versteckte Verzeichnisse ausschließen:
find -path './[^.]*' -prune -type d
So führen Sie mehrere Befehle für die zurückgegebenen Werte aus (ein sehr ausgeklügeltes Beispiel):
find -path './[^.]*' -prune -type d -print0 | xargs -0 -I '{}' sh -c \
"printf 'first: %-40s' '{}'; printf 'second: %s\n' '{}'"
Anstelle von 'sh -c' kann auch 'bash -c' usw. verwendet werden.
... -print0 | xargs -0 ...wenn Sie die genauen Namen nicht kennen.
find * | while read file; do ...
Sie können alle Verzeichnisse einschließlich versteckter Verzeichnisse (beginnend mit einem Punkt) in einer Zeile und mit mehreren Befehlen durchlaufen:
for file in */ .*/ ; do echo "$file is a directory"; done
Wenn Sie Symlinks ausschließen möchten:
for file in *; do
if [[ -d "$file" && ! -L "$file" ]]; then
echo "$file is a directory";
fi;
done
Hinweis: die Liste mit */ .*/Arbeiten in der Bash, sondern zeigt auch die Ordner .und ..während in zsh wird es nicht diese zeigt aber einen Fehler aus , wenn es keine versteckte Datei in dem Ordner ist
Eine sauberere Version, die versteckte Verzeichnisse enthält und ../ ausschließt, enthält die Option dotglob:
shopt -s dotglob
for file in */ ; do echo "$file is a directory"; done
(oder setopt dotglobin zsh)
Sie können dotglob mit deaktivieren
shopt -u dotglob
Dies wird den vollständigen Pfad in jedem Verzeichnis in der Liste enthalten:
for i in $(find $PWD -maxdepth 1 -type d); do echo $i; done
Verwenden Sie findmit -exec, um die Verzeichnisse zu durchlaufen und eine Funktion in der Option exec aufzurufen :
dosomething () {
echo "doing something with $1"
}
export -f dosomething
find -path './*' -prune -type d -exec bash -c 'dosomething "$0"' {} \;
Verwenden Sie shopt -s dotgloboder shopt -u dotglob, um versteckte Verzeichnisse ein- oder auszuschließen
ls -l | grep ^d
oder:
ll | grep ^d
Sie können es als Alias festlegen
lsAntwort unterscheidet, in der Verzeichnisse aufgelistet sind .
ls: mywiki.wooledge.org/ParsingLs