Geçmeli anahtar kutusu?


193

Bash (ideal olarak büyük / küçük harfe duyarlı olmayan) geçiş vakaları ile anahtar deyiminin doğru sözdizimini arıyorum. PHP ben programlamak istiyorum:

switch($c) {
    case 1:
        do_this();
        break;
     case 2:
     case 3:
        do_what_you_are_supposed_to_do();
        break;
     default:
        do_nothing(); 
}

Aynı şeyi Bash'de istiyorum:

case "$C" in
    "1")
        do_this()
        ;;
    "2")
    "3")
        do_what_you_are_supposed_to_do()
        ;;
    *)
        do_nothing();
        ;; 
esac

Bu bir şekilde çalışmaz: do_what_you_are_supposed_to_do()$ C 2 VEYA 3 olduğunda işlev başlatılmalıdır.


4
Parens ile çağrı işlevlerini kullanmayın !!! Bir işlevi bash içinde bir işlev tanımlayabildiğinizden function fname { echo "Inside fname"; return 0; }veya fname() { echo "inside fname"; return 0; }bir işlev çağrısına parens yerleştirebileceğiniz bir işlev tanımı gibi görünebilir. Fonksiyonlar gibi başka bir komut satırı programı gibi çağrılmalıdır mv, cp, rsync, ls, cdfname yüzden mi biz dediğimiz bu durumda ... vs: fname $ARGS.
Charles Addis

do_nothing()bir SKIP bildirimi olacak mı? Kullanın :.
sjas

Yanıtlar:


309

|"Veya" için dikey bir çubuk ( ) kullanın .

case "$C" in
"1")
    do_this()
    ;;
"2" | "3")
    do_what_you_are_supposed_to_do()
    ;;
*)
    do_nothing()
    ;;
esac

30
Veya bu basit durumda bir karakter sınıfı[23])
SiegeX

4
@Mischka - Bu cevabı kabul etmediğini not ediyorum, bunun nedeni sorunun çözülme kısmına cevap vermemesi mi? Düşüş mantığı, daha önce özel işlemin gerçekleştirilmesi gerektiğinde yararlıdır do_what_you_are_supposed_to_do(), hem "2" hem de "3" ün tek bir kutuya daraltılması bunu ele almaz . Soruyu daha net hale getirmek için düzenlemenin makul olup olmadığından emin değilim, çünkü birçok kişinin bu yanıtı yararlı bulduğu açıktır.
Tyson

1
@Tyson Kayıt olmamış bir kullanıcı olduğu için OP cevabı kabul etmedi. "Düşen" mantığa gelince, normal olarak programcılar tarafından anlaşıldığı gibi, soru gövdesi düşme mantığı değil , bir durumun çöküşünü gösterir . (Bildirim kullanımı breakphp kodunda.) Bu tarihte cevapların birçoğu kılacak, soru ya da Başlığı düzenleme yapmak yapılmamalıdır muhtemelen mantık sonbahar-yoluyla sağlamak ve. Fall-through, diğer kullanıcılar tarafından yapılan birkaç düzenlemeye kadar başlıkta değildi, ancak şimdi geri almak için çok geç.
user7412956

100

Son bashsürümler ;&, aşağıdakilerin yerine kullanarak düşmeye izin verir ;;: ayrıca, ;;&orada kullanarak vaka kontrollerinin sürdürülmesine de izin verir .

for n in 4 14 24 34
do
  echo -n "$n = "
  case "$n" in
   3? )
     echo -n thirty-
     ;;&   #resume (to find ?4 later )
   "24" )
     echo -n twenty-
     ;&   #fallthru
   "4" | [13]4)
     echo -n four 
     ;;&  # resume ( to find teen where needed )
   "14" )
     echo -n teen
  esac
  echo 
done

örnek çıktı

4 = four
14 = fourteen
24 = twenty-four
34 = thirty-four

1
Bu örnekteki bu mantığı takip etmek zordu. Ayrıca, bu örneğin gerçekten ;&ve ile arasındaki farkı gösterdiğini sanmıyorum ;;&. Değiştim "24"için ;;& # resumeve kullanmak ne zaman ben hala merak ediyorum bu yüzden, aynı sonuçları aldık ;&fallthrough.
wisbucky

1
karmaşık bir şey için basit bir örnek - Değiştim ?4için [13]4daha belirgin hale getirmek için, ve değişim bir kırılma değişiklik yapmak
Jasen

26
  • ()Tanımlamak istemediğiniz sürece bash'daki işlev adlarının arkasında kullanmayın .
  • Kullanım [23]halinde eşleşecek 2veya3
  • statik dize durumları ''yerine""

İçerilirse "", yorumlayıcı (gereksiz yere) eşleştirmeden önce değerdeki olası değişkenleri genişletmeye çalışır.

case "$C" in
'1')
    do_this
    ;;
[23])
    do_what_you_are_supposed_to_do
    ;;
*)
    do_nothing
    ;;
esac

Büyük / küçük harfe duyarlı olmayan eşleme için karakter sınıflarını kullanabilirsiniz (gibi [23]):

case "$C" in

# will match C='Abra' and C='abra'
[Aa]'bra')
    do_mysterious_things
    ;;

# will match all letter cases at any char like `abra`, `ABRA` or `AbRa`
[Aa][Bb][Rr][Aa])
    do_wild_mysterious_things
    ;;

esac

Ama abrahiçbir zaman çarpmadı çünkü ilk dava ile eşleşecek.

Gerekirse ;;, ilk durumda aşağıdaki durumlarda da eşleşmeler için test yapmaya devam edebilirsiniz. ( ;;atlar esac)


case "${C,,}" inDurum önemli değilse C'yi küçük harfe dönüştürebilirsiniz
Sprinterfreak

1
Atlarsanız ne olur ;;? ;&Geçiş için kullanmanız gerekmiyor mu?
HelloGoodbye

1
Teste devam etmek istiyorsam ;; kullanmam gerektiğini ihmal edersem bir sözdizimi hatası alıyorum ;;&.
Jasen

do_wild_mysterious_thingsgünümü yaptı
Julien__

14

Bunu dene:

case $VAR in
normal)
    echo "This doesn't do fallthrough"
    ;;
special)
    echo -n "This does "
    ;&
fallthrough)
    echo "fall-through"
    ;;
esac

1
bu çok yararlı bir ipucu. En azından Bash 4.3.11 için. Ben başkalarını denemek için rahatsız etmedim.
Daniel

3
Not: Bu, macOS'ta hala varsayılan bash olan bash 3.2 için çalışmaz.
Danny Kirchmeier

13

Değerler tamsayı ise, sürekli olmayan değerler için [2-3]veya kullanabilirsiniz [5,7,8].

#!/bin/bash
while [ $# -gt 0 ];
do
    case $1 in
    1)
        echo "one"
        ;;
    [2-3])
        echo "two or three"
        ;;
    [4-6])
        echo "four to six"
        ;;
    [7,9])
        echo "seven or nine"
        ;;
    *)
        echo "others"
        ;;
    esac
    shift
done

Değerler dize ise kullanabilirsiniz |.

#!/bin/bash
while [ $# -gt 0 ];
do
    case $1 in
    "one")
        echo "one"
        ;;
    "two" | "three")
        echo "two or three"
        ;;
    *)
        echo "others"
        ;;
    esac
    shift
done

shiftsonunda ne için?
Milkncookiez

1
shiftCLI bağımsız değişkenleri listesindeki ilk bağımsız değişkeni kaldırır. Temelde bu döngü her yinelemesi her zaman $1CLI argümanlar listesinden her argüman yardımı ile kullanılır shift.
rashok
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.