2010-10-25 8 views
26

Szybkie tła:Bash dla pętli na Directories

$ ls src 
file1 file2 dir1 dir2 dir3 

Scenariusz:

#!/bin/bash 

for i in src/* ; do 
    if [ -d "$i" ]; then 
    echo "$i" 
    fi 
done 

wyjściowa:

src/dir1 
src/dir2 
src/dir3 

Jednakże chcę to czytać:

dir1 
dir2 
dir3 

Teraz zdaję sobie sprawę, że mogę sed/awk wyjścia, aby usunąć "src /", ale jestem ciekawy, czy istnieje lepszy sposób o tym. Być może za pomocą pętli find + while.

Odpowiedz

16

Czy ta zamiast na linii echo:

echo $(basename "$i") 
+0

widzę zaktualizowaniu post do odczytu * basename * zamiast * DIRNAME * ding, ding, ding POPRAWNIE !!! : D Dzięki, przyjmuję twoją odpowiedź – BassKozz

+0

Nauczyłem się tego bryłka zaledwie 2 dni temu z książki O'Rielly'ego. Mogłabym zaoszczędzić mi godzin snu, gdybym wiedział to lata temu. – Synesso

3

Korzystając basename jak:

if [ -d "$i" ]; then 
    basename "$i" 
fi 
10

Nie potrzeba rozwidlone zewnętrznego procesu:

echo "${i##*/}" 

Używa „usuń najdłuższy pasujący prefiks "parameter expansion. Model */ jest wzorem, więc usunie wszystko od początku łańcucha aż do ostatniego ukośnika włącznie. Jeśli nie ma ukośnika w wartości $i, to jest taki sam jak "$i".

To szczególne rozszerzenie parametru to specified in POSIX i jest częścią spuścizny oryginalnej powłoki Bourne'a. Jest ona dostępna we wszystkich powłokach typu bourne (sh, popiół, kreska, ksh, bash, zsh, itd.). Wiele spośród bogatych w funkcje powłok (na przykład ksh, bash i zsh) ma inne rozszerzenia, które mogą obsłużyć jeszcze więcej bez angażowania procesów zewnętrznych.

8

Jeśli zrobisz cd na początku skryptu, powinien on zostać przywrócony po zakończeniu skryptu.

#!/bin/bash 

cd src 
for i in * ; do 
    if [ -d "$i" ]; then 
    echo "$i" 
    fi 
done 
+2

powinno ... ale jeśli użyjesz polecenia '.' lub' source' do wywołania skryptu, nie będzie. Zamiast tego użyj 'pushd' i' popd'. – Benoit