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 -P
betrifft 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 for
Schleife nicht übersprungen, sondern genau einmal ausgeführt, wobei d
gilt */
:
#!/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 f
es sich um ein Verzeichnis handelt, und gibt ein Echo aus, f
wenn die Bedingung wahr ist. Wenn f
gleich */
, echo $f
wird nicht ausgeführt.
shopt -s nullglob
.
Wenn Sie spezifischere Dateien als nur Verzeichnisse auswählen müssen, verwenden Sie diese find
und ü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 dotglob
diese Option, um versteckte Verzeichnisse (oder setopt dotglob
/ unsetopt dotglob
in 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 find
Optionen
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 dotglob
for verwenden bash
, um versteckte Verzeichnisse einzuschließen. Ihr wird auch enthalten .
. Beachten Sie auch, dass dies -maxdepth
keine Standardoption -prune
ist.
dotglob
Option ist interessant, dotglob
gilt 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 dotglob
in 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 find
mit -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 dotglob
oder 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
ls
Antwort unterscheidet, in der Verzeichnisse aufgelistet sind .
ls
: mywiki.wooledge.org/ParsingLs