Chcę, aby mój skrypt powłoki odwiedził wszystkie podkatalogi w katalogu głównym. Zrób coś w katalogach, wyślij dane wyjściowe do pliku buforowania i przejdź do następnego katalogu. Rozważ główny katalog = / tmp podkatalog = ABCD (cztery podkatalogi)
Chcę, aby mój skrypt powłoki odwiedził wszystkie podkatalogi w katalogu głównym. Zrób coś w katalogach, wyślij dane wyjściowe do pliku buforowania i przejdź do następnego katalogu. Rozważ główny katalog = / tmp podkatalog = ABCD (cztery podkatalogi)
Odpowiedzi:
Użyj for
pętli:
for d in $(find /path/to/dir -maxdepth 1 -type d)
do
#Do something, the directory is accessible with $d:
echo $d
done >output_file
Przeszukuje tylko podkatalogi katalogu /path/to/dir
. Zauważ, że powyższy prosty przykład zawiedzie, jeśli nazwy katalogów zawierają spacje lub znaki specjalne. Bezpieczniejsze podejście to:
find /tmp -maxdepth 1 -type d -print0 |
while IFS= read -rd '' dir; do echo "$dir"; done
Lub wprost bash
:
for d in /path/to/dir/*; do
if [ -d "$d" ]; then
echo "$d"
fi
done
(zauważ, że w przeciwieństwie do find
tego rozważa również dowiązania symboliczne do katalogów i wyklucza ukryte)
find
podobnych wyników.
date +"%m%d20%Y"
| xargs echo echo $ d
date +"%m%d20%Y"
| xargs echo echo $ d Oczekiwany wynik to ls -ltr ze wszystkich podkatalogów . Powyższa pętla nie działa
Jestem kompletnym bash
nowicjuszem, ale weteranem ONZ * X. Chociaż niewątpliwie można tego dokonać w skryptach powłoki Bash, w dawnych czasach to robiliśmy find [-maxdepth <levels>] <start-dir> -exec <command> ;
. Możesz zrobić man find
i bawić się, może dopóki ktoś nie powie ci, jak to zrobić bash
!
find
poleceń zewnętrznych .
$(find...)
o złą praktykę .
Wygląda na to, że chcesz mieć nazwy plików w każdym podkatalogu; ls -l | awk
nie jest wystarczająco wytrzymała, na co, jeśli te nazwy plików zawierają białymi znakami i / lub znaki nowej linii? Poniższe find
działałoby nawet dla find
tych, którzy nie mają -maxdepth
szans na ich spełnienie :
find . ! -name . -type d -prune -exec sh -c '
cd "$1" && \
find "." ! -name . -prune -type f
' {} {} \;
Jest to również możliwe przy użyciu ls, grep i tr
for dir in $(ls -1FA | grep / | tr -d /); do echo $dir/something; done
ls -1FA | grep / | tr -d / | while IFS= read -r TD; do echo $TD/something; done
du / sed może być również używany jako selektor, jeśli twojemu ls brakuje powyższych opcji
du --max-depth=1 | sed -e 's/^.*\.\///' | grep -v '\.$'
Warto pamiętać, że te przykłady zwracają ukryte katalogi i wykluczają katalogi nadrzędne i bieżące
ls
zapisuje jeden plik w wierszu (co -1
określa opcja), gdy standardowym wyjściem jest potok (więc jest zbyteczny w twoich odpowiedziach). (2) Analiza wyniku ls
jest złym pomysłem - zobacz to i to . Twoja pierwsza odpowiedź nie powiedzie się, jeśli katalogi mają spacje (lub znaki nowej linii) w swoich nazwach, a wszystkie zawiodą, jeśli będą miały nazwy nowych linii. (3) Zawsze powinieneś cytować zmienne powłoki (np. "$dir"
), Chyba że masz dobry powód, aby tego nie robić i jesteś pewien, że wiesz, co robisz.