केस + सिंटैक्स में समान या कम या अधिक लागू करने के लिए कैसे


9

मेरा लक्ष्य (केवल case+ esac) के साथ संख्या की एक श्रेणी को सत्यापित करना है , और सीमा को प्रिंट करना है। उदाहरण के लिए:

  • यदि संख्या 0 और 80 के बीच है, तो प्रिंट करें >=0<=80
  • यदि संख्या 81 और 100 के बीच है तो प्रिंट करें >=81<=100
  • आदि।

मेरी स्क्रिप्ट के नीचे समस्या केवल प्रिंट के >=0<=90बीच की संख्या 0 और 9. के बीच की संख्या मेरी स्क्रिप्ट को ठीक करने के लिए कैसे है, ताकि यह संख्या सीमा के अनुसार सही आउटपुट प्रिंट करे?

#!/bin/ksh
read number 
case $number in 
 [0-80])  echo ">=0<=80";; 
 [81-100]) echo ">=81<=100";; 
 [101-120]) echo ">=101<=120";;
 [121-300]) echo ">=121<=300";;
esac

जवाबों:


6

caseहै केवल पैटर्न मिलान के लिए, यह गणित मूल्यांकन नहीं करेंगे (शायद सिवाय अगर आप समझते हैं zshकी <x-y>विस्तारित पैटर्न मिलान ऑपरेटर)। [...]केवल मैच के लिए है एक चरित्र (या क्रमवार तत्व के भीतर निर्दिष्ट सेट के आधार पर कुछ कार्यान्वयन में)। तो उदाहरण के लिए [0-80]मेल खाने वाली एक चरित्र अगर यह में से एक है 0करने के लिए 8या 0(यह है कि, में से एक 0, 1, 2, 3, 4, 5, 6, 7, 8)।

आप पैटर्न के साथ संख्याओं का मिलान कर सकते हैं जैसे:

case $(($number)) in
  ([0-9]|[1-7][0-9]|80) echo ">=0<=80";;
  (8[1-9]|9[0-9]|100) echo ">=81<=100";;
  ... and so on
esac

लेकिन आप आसानी से देख सकते हैं कि यह सही उपकरण नहीं है।

[...]से मेल खाता है एक , निर्दिष्ट अक्षरों की सूची के खिलाफ चरित्र तो [121-300]किसी भी चरित्र या तो 1, 2, 1 से 3, 0 या 0 है कि, तो यह रूप में एक ही है के लिए मैच [0-3]या [0123]

उपयोग:

if [ "$number" -ge 0 ] && [ "$number" -le 80 ]; then
  echo ">=0<=80"
elif [ "$number" -ge 81 ] &&  [ "$number" -le 100 ]; then
  echo ">=81<=100"
elif ... and so on
  ...
fi

उपयोग करने का एक और तरीका caseहोगा:

case $((
  (number >= 0 && number <= 80)   * 1 +
  (number > 80 && number <= 100)  * 2 +
  (number > 100 && number <= 120) * 3 +
  (number > 120 && number <= 300) * 4)) in
  (1) echo ">=0<=80";;
  (2) echo ">=81<=100";;
  (3) echo ">=101<=120";;
  (4) echo ">=121<=300";;
  (0) echo "None of the above";;
esac

या टर्नरी ऑपरेटर का उपयोग करें ( x ? y : z):

case $((
  number >= 0 && number <= 80   ? 1 :
  number > 80 && number <= 100  ? 2 :
  number > 100 && number <= 120 ? 3 :
  number > 120 && number <= 300 ? 4 : 0)) in...

या @mikeserv की तरह, बॉक्स के बाहर सोचें, तर्क को उल्टा करें caseऔर 1उन अंकगणितीय तुलनाओं के मूल्य के विरुद्ध मिलान करें


1
+1, विचार करें if [ n < 0 ] - elif [ n <= 80 ] - elif [ n <= 100 ] ... - else। कम टाइपिंग, कम त्रुटि-प्रवण।
पीटरफ

@peterph इसे चलाने में भी अधिक समय लगता है।
केन शार्प

4

वास्तव में यह करना बहुत आसान है। इसके बारे caseमें बात यह है कि यह हमेशा केवल उतना ही विस्तार करेगा जितना एक पैटर्न के खिलाफ पहला मैच खोजने के लिए आवश्यक है। यह व्यवहार है। और इसलिए आप इसे केवल एक ज्ञात स्ट्रिंग के साथ सेट कर सकते हैं और पैटर्न के विस्तार का मूल्यांकन कर सकते हैं।

case  1:${number:--} in
(1:*[!0-9]*|1:0*[89]*)
  ! echo NAN
;;
($((number<81))*)
    echo "$number >=0<=80"
;;
($((number<101))*)
    echo "$number >=81<=100"
;;
($((number<121))*)
    echo "$number >=101<=120"
;;
($((number<301))*)
    echo "$number >=121<=300"
;;
esac

caseपैटर्न में एक अग्रणी 1 खोजने के लिए उन पैटर्न से किसी भी अधिक का विस्तार कभी नहीं होगा। उपयोगकर्ता इनपुट के साथ काम करते समय यह विशेष रूप से महत्वपूर्ण है, क्योंकि इसका मतलब है कि आप $numberइससे पहले कि कभी भी इसे गणित के विस्तार में डालते हैं, उसी मामले में एक अंकगणितीय विस्तार के संदर्भ में डालने की कोशिश करने से पहले सामग्री को सुरक्षित रूप से सत्यापित कर सकते हैं ।


👍 मुझे वह तरीका पसंद है जो आप बॉक्स के बाहर / आसपास सोचते हैं।
स्टीफन चेज़लस

@ स्टीफनचेज़ेलस - मुझे पसंद है case। कुछ शांत सामान आप $((गणित ))और case- विशेष रूप से आस-पास के असाइनमेंट्स के साथ कर सकते हैं, जो तब तक कभी नहीं होते हैं जब तक कि उन्हें ज़रूरत न हो - और आप पार्स ट्री भी बना सकते हैं जो नेस्टेड रिकर्स का विस्तार करते हैं यदि आप एक aliasचेन के साथ पैटर्न को पॉप्युलेट करते हैं । इसका सबसे तेज़ तरीका ive को चरित्र अनुवाद जैसे सामान करने के लिए और बाइट मान के लिए वर्ण स्वैप करने के लिए मिला। यह बहुत तेज़ हो सकता है - C-Locale ASCII + <> बहुत खराब स्थिति 7 मूल POSIX पैटर्न विस्तार है।
21

1

यह बहुत अच्छा नहीं है लेकिन आप इसका उपयोग कर सकते हैं:

 #!/bin/ksh

read number  

case $number in
[0-9]|[1-7][0-9]|80) echo  echo ">=0<=80";;
8[1-9]|9[0-9]|100) echo ">=81<=100";;
10[1-9]|11[0-9]|120) echo ">=101<=120";;
12[1-9]|130) echo ">=121<=300";;
esac

आप "001" या "0x99" जैसे नंबरों को कवर करने के लिए $ (($ नंबर)) के साथ संख्या "canonify" करना चाह सकते हैं ... जो "12" और "12 + 12" के लिए भी कवर करेगा जो हो सकता है या हो सकता है वांछनीय नहीं है।
स्टीफन चेज़लस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.