2010-10-25 36 views
26

Sfondo rapida:Bash For-loop sulla directory

$ ls src 
file1 file2 dir1 dir2 dir3 

Script:

#!/bin/bash 

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

uscita:

src/dir1 
src/dir2 
src/dir3 

Tuttavia, voglio che leggere:

dir1 
dir2 
dir3 

Ora mi rendo conto che potrei sed/awk l'output per rimuovere "src /" tuttavia sono curioso di sapere se c'è un modo migliore per farlo. Forse usando invece find + while-loop.

risposta

16

fare questo, invece, per la linea echo:

echo $(basename "$i") 
+0

vedo che hai aggiornato il tuo post per leggere * nome base * invece di * * dirname ding, ding, ding CORRETTO !!! : D Grazie, accetterò la tua risposta – BassKozz

+0

Ho imparato questo nugget solo 2 giorni fa da un libro di O'Rielly. Avrei potuto risparmiarmi ore di stupidaggini se lo avessi saputo anni fa. – Synesso

3

Uso basename come:

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

Non c'è bisogno di sborsare un processo esterno:

echo "${i##*/}" 

utilizza il “rimuovere il prefisso di corrispondenza più lungo "parameter expansion. */ è lo schema, quindi eliminerà tutto dall'inizio della stringa fino a includere l'ultima barra. Se non c'è nessuna barra nel valore di $i, allora è lo stesso di "$i".

Questa particolare espansione di parametro è specified in POSIX e fa parte del retaggio della shell Bourne originale. Esso è supportato in tutte le shell Bourne-like (sh, cenere, cruscotto, ksh, bash, zsh, etc.). Molte delle shell ricche di funzionalità (ad esempio ksh, bash e zsh) hanno altre espansioni che possono gestire ancora di più senza coinvolgere processi esterni.

8

Se si esegue uno cd all'inizio dello script, è necessario ripristinarlo al termine dello script.

#!/bin/bash 

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

dovrebbe ... ma se si usa il comando '.' o' source' per invocare lo script, non lo farà. Piuttosto usa 'pushd' e' popd'. – Benoit

Problemi correlati