Odpowiedzi:
Możesz określić ukośnik na końcu, aby pasował tylko do katalogów:
for d in */ ; do
echo "$d"
done
[[ -L $d ]]czy $ d jest dowiązaniem symbolicznym.
set -Pwpływa tylko na polecenia zmieniające katalog. sprunge.us/TNac
[[ -L "$f" ]]nie wyklucza dowiązań symbolicznych w tym przypadku za pomocą */, musisz rozebrać ukośnik końcowy za pomocą [[ -L "${f%/}" ]](patrz Test linku z ukośnikiem końcowym )
Możesz przetestować za pomocą -d:
for f in *; do
if [ -d "$f" ]; then
# $f is a directory
fi
done
Jest to jeden z operatorów testowania plików .
if [[ -d "$f" && ! -L "$f" ]]wykluczy dowiązania symboliczne
if [[ "$f" = "*" ]]; then continue; fi
Uważaj, że rozwiązanie tej choroby, choć eleganckie, może wywołać nieoczekiwane zachowanie, jeśli w bieżącym katalogu nie ma dostępnych katalogów. W tym stanie, zamiast pomijania forpętli, bash uruchomi pętlę dokładnie raz, gdzie djest równa */:
#!/usr/bin/env bash
for d in */; do
# Will print */ if no directories are available
echo $d
done
Zalecam użycie następujących elementów w celu ochrony przed tym przypadkiem:
#!/usr/bin/env bash
for f in *; do
if [ -d ${f} ]; then
# Will not run if no directories are available
echo $f
fi
done
Ten kod będzie przechodził przez wszystkie pliki w bieżącym katalogu, sprawdza, czy fjest to katalog, a następnie echo, fjeśli warunek zwraca wartość true. Jeśli fjest równe */, echo $fnie zostanie wykonane.
shopt -s nullglob.
Jeśli musisz wybrać bardziej szczegółowe pliki, użyj tylko katalogów findi przekaż je do while read:
shopt -s dotglob
find * -prune -type d | while IFS= read -r d; do
echo "$d"
done
Służy shopt -u dotglobdo wykluczania ukrytych katalogów (lub setopt dotglob/ unsetopt dotglobw zsh).
IFS=aby uniknąć podziału nazw plików zawierających jeden z $IFS, na przykład:'a b'
zobacz AsymLabs odpowiedzieć poniżej więcej findopcji
edycja:
Jeśli chcesz utworzyć wartość wyjściową z pętli while, możesz obejść dodatkową podpowłokę za pomocą tej sztuczki:
while IFS= read -r d; do
if [ "$d" == "something" ]; then exit 1; fi
done < <(find * -prune -type d)
Możesz użyć do tego czystej bash, ale lepiej użyć find:
find . -maxdepth 1 -type d -exec echo {} \;
(znajdź dodatkowo będzie zawierać ukryte katalogi)
shopt -s dotglobdo, bashaby dołączyć ukryte katalogi. Twój będzie również obejmować .. Należy również pamiętać, że -maxdepthnie jest to standardowa opcja ( -prunejest).
dotglobOpcja jest interesująca, ale dotglobodnosi się wyłącznie do wykorzystania *. find .zawsze będzie zawierać ukryte katalogi (a także bieżący katalog)
Odbywa się to w celu znalezienia zarówno widocznych, jak i ukrytych katalogów w bieżącym katalogu roboczym, z wyłączeniem katalogu głównego:
aby po prostu przeglądać katalogi:
find -path './*' -prune -type d
w celu dołączenia dowiązań symbolicznych w wyniku:
find -L -path './*' -prune -type d
zrobić coś z każdym katalogiem (z wyłączeniem dowiązań symbolicznych):
find -path './*' -prune -type d -print0 | xargs -0 <cmds>
aby wykluczyć ukryte katalogi:
find -path './[^.]*' -prune -type d
aby wykonać wiele poleceń na zwróconych wartościach (bardzo przemyślany przykład):
find -path './[^.]*' -prune -type d -print0 | xargs -0 -I '{}' sh -c \
"printf 'first: %-40s' '{}'; printf 'second: %s\n' '{}'"
zamiast „sh -c” można również użyć „bash -c” itp.
... -print0 | xargs -0 ...jeśli nie wiesz, jakie są dokładne nazwy.
find * | while read file; do ...
Możesz przewijać wszystkie katalogi, w tym ukryte katalogi (zaczynające się od kropki) w jednym wierszu i wiele poleceń za pomocą:
for file in */ .*/ ; do echo "$file is a directory"; done
Jeśli chcesz wykluczyć dowiązania symboliczne:
for file in *; do
if [[ -d "$file" && ! -L "$file" ]]; then
echo "$file is a directory";
fi;
done
Uwaga: za pomocą listy */ .*/działa w bash, ale również wyświetla foldery, .a ..jednocześnie w zsh nie pokaże tych, ale wygeneruje błąd, jeśli nie ma ukryty plik w folderze
Czystsza wersja, która będzie zawierać ukryte katalogi i wykluczać ../ będzie dostępna z opcją dotglob:
shopt -s dotglob
for file in */ ; do echo "$file is a directory"; done
(lub setopt dotglobw Zsh)
możesz rozbroić dotglob za pomocą
shopt -u dotglob
Obejmuje to pełną ścieżkę do każdego katalogu na liście:
for i in $(find $PWD -maxdepth 1 -type d); do echo $i; done
Użyj za findpomocą, -execaby przeglądać katalogi i wywoływać funkcję w opcji exec:
dosomething () {
echo "doing something with $1"
}
export -f dosomething
find -path './*' -prune -type d -exec bash -c 'dosomething "$0"' {} \;
Użyj shopt -s dotgloblub, shopt -u dotglobaby włączyć / wyłączyć ukryte katalogi
ls -l | grep ^d
lub:
ll | grep ^d
Możesz ustawić go jako alias
lsodpowiedzi opartej na tej liście , która zawiera katalogi.