Piszę skrypt w bashu na Linuksie i muszę przejść przez wszystkie nazwy podkatalogów w podanym katalogu. Jak mogę przeglądać te katalogi (i pomijać zwykłe pliki)?
Na przykład:
podany katalog /tmp/
czy zawiera następujące podkatalogi:/tmp/A, /tmp/B, /tmp/C
Chcę odzyskać A, B, C.
Odpowiedzi:
Krótkie wyjaśnienie:
find
znajduje pliki (dość oczywiste).
jest bieżącym katalogiem, który pocd
jest/tmp
(IMHO jest to bardziej elastyczne niż posiadanie/tmp
bezpośrednio wfind
poleceniu. Masz tylko jedno miejscecd
, do zmiany, jeśli chcesz, aby więcej akcji było wykonywanych w tym folderze)-maxdepth 1
i-mindepth 1
upewnij się, żefind
wygląda tylko w bieżącym katalogu i nie włącza.
się do wyniku-type d
szuka tylko katalogów-printf '%f\n
wypisuje tylko nazwę znalezionego folderu (plus nowa linia) dla każdego trafienia.Zrobione!
źródło
while..done
pętli możesz zwariować.find
„s-exec
opcja pozwala uruchamiać dowolne polecenie dla każdego pliku / katalogu.Wszystkie dotychczasowe odpowiedzi są używane
find
, więc tutaj jest tylko powłoka. Nie potrzebujesz zewnętrznych narzędzi w Twoim przypadku:źródło
find
kiedy możesz dołączyć ukośnik do symbolu wieloznacznegofor dir in */; do echo $dir; done
jest dla katalogów w bieżącym katalogu.dir=${dir%*/}
iecho ${dir##*/}
robi./tmp/*/
, rozsądnie byłoby uwzględnić sprawdzenie, czy katalog rzeczywiście istnieje.Możesz przeglądać wszystkie katalogi, w tym katalogi ukryte (zaczynając od kropki) za pomocą:
uwaga: użycie listy
*/ .*/
działa w zsh tylko wtedy, gdy istnieje przynajmniej jeden ukryty katalog w folderze. W bash pokaże również.
i..
Inną możliwością dołączenia przez bash ukrytych katalogów byłoby użycie:
Jeśli chcesz wykluczyć linki symboliczne:
Aby wyprowadzić tylko końcową nazwę katalogu (A, B, C zgodnie z pytaniami) w każdym rozwiązaniu, użyj tego w pętlach:
Przykład (działa to również z katalogami zawierającymi spacje):
źródło
Działa z katalogami zawierającymi spacje
Zainspirowany Sorpigalem
Oryginalny post (nie działa ze spacjami)
Zainspirowany przez Boldewyn : Przykład pętli z
find
poleceniem.źródło
źródło
basename
. Wolałbym to od mojej odpowiedzi.Najczęściej używam techniki
find | xargs
. Na przykład, jeśli chcesz, aby każdy plik w tym katalogu i wszystkie jego podkatalogi były czytelne dla wszystkich, możesz wykonać:-print0
Opcja kończy się znakiem NULL zamiast przestrzeni. Ta-0
opcja dzieli dane wejściowe w ten sam sposób. Więc to jest kombinacja do użycia w plikach ze spacjami.Możesz sobie wyobrazić ten łańcuch poleceń jako pobierający wyjście każdego wiersza
find
i przyklejający go na końcuchmod
polecenia.Jeśli polecenie, które chcesz uruchomić jako argument w środku zamiast na końcu, musisz być trochę kreatywny. Na przykład musiałem przejść do każdego podkatalogu i uruchomić polecenie
latemk -c
. Więc użyłem (z Wikipedii ):Ma to skutek
for dir $(subdirs); do stuff; done
, ale jest bezpieczne w przypadku katalogów ze spacjami w nazwach. Ponadto oddzielne wywołaniastuff
są wykonywane w tej samej powłoce, dlatego w moim poleceniu musimy wrócić do bieżącego katalogu za pomocąpopd
.źródło
minimalna pętla bash, z której możesz zbudować (na podstawie odpowiedzi ghostdog74)
spakować całą masę plików według katalogu
źródło
directory
, nie tylko podkatalogów.find . -type d -maxdepth 1
źródło
Jeśli chcesz wykonać wiele poleceń w pętli for, możesz zapisać wynik
find
withmapfile
(bash> = 4) jako zmienną i przejść przez tablicę za pomocą${dirlist[@]}
. Działa również z katalogami zawierającymi spacje.find
Poleceń opiera się na odpowiedź przez Boldewyn. Więcej informacji na tematfind
polecenia można znaleźć tam.źródło