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 -P
wpł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 for
pętli, bash uruchomi pętlę dokładnie raz, gdzie d
jest 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 f
jest to katalog, a następnie echo, f
jeśli warunek zwraca wartość true. Jeśli f
jest równe */
, echo $f
nie zostanie wykonane.
shopt -s nullglob
.
Jeśli musisz wybrać bardziej szczegółowe pliki, użyj tylko katalogów find
i 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 dotglob
do wykluczania ukrytych katalogów (lub setopt dotglob
/ unsetopt dotglob
w 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 find
opcji
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 dotglob
do, bash
aby dołączyć ukryte katalogi. Twój będzie również obejmować .
. Należy również pamiętać, że -maxdepth
nie jest to standardowa opcja ( -prune
jest).
dotglob
Opcja jest interesująca, ale dotglob
odnosi 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 dotglob
w 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 find
pomocą, -exec
aby 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 dotglob
lub, shopt -u dotglob
aby włączyć / wyłączyć ukryte katalogi
ls -l | grep ^d
lub:
ll | grep ^d
Możesz ustawić go jako alias
ls
odpowiedzi opartej na tej liście , która zawiera katalogi.