गिरावट के साथ स्विच केस?


193

मैं बैश (आदर्श रूप से केस-असंवेदनशील) में गिरावट वाले मामलों के साथ स्विच स्टेटमेंट के सही सिंटैक्स की तलाश कर रहा हूं। PHP में मैं इसे पसंद करता हूँ:

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

मुझे बैश में भी ऐसा ही चाहिए:

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

यह किसी तरह काम नहीं करता है: do_what_you_are_supposed_to_do()$ C 2 OR 3 होने पर फ़ंक्शन को निकाल दिया जाना चाहिए।


4
Parens के साथ कॉल फ़ंक्शन का उपयोग न करें !!! चूँकि आप फंक्शन को परिभाषित कर सकते हैं function fname { echo "Inside fname"; return 0; }या तो फंक्शन का उपयोग कर सकते हैं या fname() { echo "inside fname"; return 0; }किसी फंक्शन कॉल पर पैरेंस लगा सकते हैं, जैसे कि यह एक फंक्शन डिफिनेशन है। कार्य किसी अन्य कमांड लाइन कार्यक्रम जैसे जैसे बुलाया जाना चाहिए mv, cp, rsync, ls, cd, आदि ... इस मामले में हम फोन में fname इतना चाहते: fname $ARGS
चार्ल्स अदीस

do_nothing()SKIP स्टेटमेंट हो सकता है का उपयोग करें :
जज

जवाबों:


309

|"या" के लिए एक ऊर्ध्वाधर पट्टी ( ) का उपयोग करें ।

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

30
या इस साधारण मामले में एक चरित्र वर्ग[23])
घेराबंदी

4
@ मिस्का - मैंने ध्यान दिया कि आपने इस उत्तर को स्वीकार नहीं किया है, क्या इसलिए कि यह प्रश्न के महत्वपूर्ण हिस्से का उत्तर नहीं देता है? निर्णायक तर्क उपयोगी है जहां विशेष प्रसंस्करण पहले होना चाहिए do_what_you_are_supposed_to_do(), दोनों "2" और "3" को एक ही मामले में ढहाने से इसे संबोधित करने में विफल रहता है। अगर यह स्पष्ट करने के लिए प्रश्न को संपादित करना उचित है तो मैं अनिश्चित हूं, क्योंकि यह स्पष्ट है कि बहुत से लोगों ने इस उत्तर को उपयोगी पाया है।
टायसन

1
@Tyson ओपी ने जवाब स्वीकार नहीं किया है, क्योंकि यह एक अपंजीकृत उपयोगकर्ता है। "फॉल-थ्रू" लॉजिक के रूप में, जैसा कि आम तौर पर प्रोग्रामर द्वारा समझा जाता है, प्रश्न निकाय स्थिति के पतन का प्रदर्शन करता है, न कि गिरे हुए तर्क के माध्यम से। (सूचना के उपयोग breakphp कोड में।) सवाल है, या इसके शीर्षक का संपादन, इस तारीख में जवाब जिनमें से कई को अमान्य होगा है प्रदान करते हैं तर्क गिरावट के माध्यम से, और शायद नहीं किया जाना चाहिए। अन्य उपयोगकर्ताओं द्वारा कई संपादन किए जाने तक फ़ॉल-थ्रू शीर्षक में नहीं था, लेकिन अब इसे वापस लेने के लिए बहुत देर हो चुकी है।
user7412956

100

हाल bashके संस्करणों की अनुमति देने के पतन के माध्यम का उपयोग करके ;&की जगह में ;;: वे भी उपयोग करके मामले की जाँच करता शुरू करने की अनुमति देते हैं ;;&वहाँ।

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

नमूना उत्पादन

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

1
इस उदाहरण में इस तर्क का पालन करना मुश्किल था। इसके अलावा, मुझे नहीं लगता कि यह उदाहरण वास्तव में ;&और के बीच के अंतर को प्रदर्शित करता है ;;&। मैं बदल "24"करने के लिए ;;& # resumeऔर एक ही परिणाम मिला है, इसलिए मैं अभी भी सोच रहा हूँ जब आप का प्रयोग करेंगे ;&fallthrough।
बुद्धिमानबीज

1
यह एक जटिल बात के लिए एक सरल उदाहरण है - मैंने इसे और अधिक स्पष्ट ?4करने के [13]4लिए बदल दिया , और आपके परिवर्तन को एक ब्रेकिंग परिवर्तन बनाने के लिए
जैसन

26
  • ()जब तक आप उन्हें परिभाषित करना पसंद नहीं करते, तब तक बाश में फ़ंक्शन नामों के पीछे का उपयोग न करें ।
  • [23]मैच 2या के मामले में उपयोग करें3
  • ''इसके बजाय स्थिर स्ट्रिंग मामलों को संलग्न किया जाना चाहिए""

यदि संलग्न है "", तो दुभाषिया (अनावश्यक रूप से) मिलान से पहले मूल्य में संभावित चर का विस्तार करने की कोशिश करता है।

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

असंवेदनशील मिलान के लिए, आप वर्ण वर्गों (जैसे [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

लेकिन abraकभी भी नहीं मारा क्योंकि यह पहले मामले से मिलान किया जाएगा।

यदि आवश्यक हो, तो आप ;;पहले मामले में भी निम्नलिखित मामलों में मैचों के लिए परीक्षण जारी रखने के लिए छोड़ सकते हैं । ( ;;कूदता है esac)


case "${C,,}" inयदि मामला महत्वपूर्ण नहीं है तो आप C को लोअरकेस में भी बदल सकते हैं
Sprinterfreak

1
यदि आप छोड़ देते हैं तो क्या होता है ;;? क्या आप ;&परित्याग के लिए उपयोग नहीं कर रहे हैं ?
हैलोगूडीबाई

1
अगर मुझे परीक्षण जारी रखना है तो मुझे ;; उपयोग करने की आवश्यकता होने पर मुझे एक सिंटैक्स त्रुटि मिलती है ;;&
जैसन

do_wild_mysterious_thingsमेरा दिन बना दिया
Julien__

14

इसे इस्तेमाल करे:

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

1
यह एक बहुत ही उपयोगी टिप है। कम से कम बैश 4.3.11 के लिए। मैंने इसे किसी अन्य पर आजमाने की जहमत नहीं उठाई।
डेनियल

3
नोट: यह bash 3.2 के लिए काम नहीं करता है, जो अभी भी macOS में डिफ़ॉल्ट बैश है।
डैनी किर्चमीयर

13

यदि मान पूर्णांक हैं, तो आप उपयोग कर सकते हैं [2-3]या आप [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

यदि मान स्ट्रिंग हैं, तो आप उपयोग कर सकते हैं |

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

shiftअंत में क्या है ?
Milkncookiez

1
shiftCLI तर्क सूची पर पहला तर्क निकालता है। मूल रूप से इस पाश के हर पुनरावृत्ति पर हमेशा $1CLI तर्क सूची से प्रत्येक तर्क प्राप्त करने के लिए उपयोग किया जाता है shift
राशोक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.