2012-10-26 11 views
6

Z góry dziękuję bardzo za pomoc!Bash - pętla for dla każdego folderu w katalogu, z wyłączeniem niektórych z nich

Mam ten kod w bash:

for d in this_folder/*  
    do  
     plugin=$(basename $d) 
     echo $plugin'?' 
     read $plugin 
    done 

który działa jak czar. Dla każdego folderu wewnątrz "this_folder", echo to jako pytanie i zapisać dane wejściowe w zmiennej o tej samej nazwie.

Ale teraz chciałbym wykluczyć niektóre foldery, więc na przykład poprosi o każdy folder w tym katalogu, TYLKO jeśli nie są to żadne z następujących folderów: globalne, wtyczki i css.

Jakieś pomysły, w jaki sposób mogę to osiągnąć?

Dzięki!

UPDATE:

ten sposób ostateczny kod wygląda następująco:

base="coordfinder|editor_and_options|global|gyro|movecamera|orientation|sa" 

> vt_conf.sh 
echo "# ========== Base"  >> vt_conf.sh 
for d in $orig_include/@($base) 
do 
    plugin=$(basename $d) 
    echo "$plugin=y"   >> vt_conf.sh 
done 
echo ''      >> vt_conf.sh 
echo "# ========== Optional" >> vt_conf.sh 
for d in $orig_include/!($base) 
do 
    plugin=$(basename $d) 
    echo "$plugin=n"   >> vt_conf.sh 
done 

Odpowiedz

6

Jeśli masz najnowszą wersję bash, można korzystać z rozszerzonego globs (shopt -s extglob):

for d in this_folder/!(global|plugins|css)/ 
do  
    plugin=$(basename "$d") 
    echo $plugin'?' 
    read $plugin 
done 
+0

Jest to bardzo dobra opcja, ale zwróci również wszystkie pliki, jeśli w folderze 'ten_folderu znajdują się zarówno katalogi, jak i pliki. Jeśli po prostu wstawisz końcowe "/" na końcu wiersza 'for' (po kryteriach'! '), To będzie działać pięknie. Również polecam (do ciebie i OP), załączając odniesienia do '$ d' między cytatami, więc może to dotyczyć spacji za pomocą spacji. –

+1

@CharlesRobertoCanato: Dobra rada, dodałem twoje sugestie – Thor

-1

Można użyć find i awk zbudować listę katalogów, a następnie zapisać wynik w zmiennej. Coś na wzór tego (niesprawdzone):

dirs=$(find this_folder -maxdepth 1 -type d -printf "%f\n" | awk '!match($0,/^(global|plugins|css)$/)') 
for d in $dirs; do 
    # ... 
done 
+0

To złamać, jeżeli istnieją nazwy plików, które zawierają biały znak lub powłoki symboli wieloznacznych, które pasują do istniejącego plik. – tripleee

7

Można użyć continue pominąć jednej iteracji pętli:

for d in this_folder/*  
    do  
     plugin=$(basename $d) 
     [[ $plugin =~ ^(global|plugins|css)$ ]] && continue 
     echo $plugin'?' 
     read $plugin 
    done 
1

Jeśli oznaczało wykluczenie jedynie katalogi o nazwach globalny, css, pluginy . To może nie być eleganckie rozwiązanie, ale zrobi to, co chcesz.

for d in this_folder/*  
do 
    flag=1 
    #scan through the path if it contains that string 
    for i in "/css/" "/plugins/" "/global/" 
    do 

    if [[ $(echo "$d"|grep "$i") && $? -eq 0 ]] 
    then 
     flag=0;break; 
    fi 
    done 

    #Only if the directory path does NOT contain those strings proceed 
    if [[ $flag -eq 0 ]] 
    then 
    plugin=$(basename $d) 
    echo $plugin'?' 
    read $plugin 
    fi 


done 
+1

Zamiast 'flag = 0; break;' możesz po prostu użyć 'continue 2'. Następnie usuń późniejsze opakowanie 'if [[$ flag -eq 0]] ...'. – dubiousjim

+0

@dubiousjim: Tak, masz rację, ale chciałem tylko, aby skrypt był prostszy do zrozumienia dla OP. – askmish

Powiązane problemy