स्ट्रिंग तुलना के लिए नहीं के बराबर ऑपरेटर का उपयोग करना


117

मैंने यह जांचने की कोशिश की कि क्या PHONE_TYPEचर में तीन वैध मान हैं।

if [ "$PHONE_TYPE" != "NORTEL" ] || [ "$PHONE_TYPE" != "NEC" ] ||
   [ "$PHONE_TYPE" != "CISCO" ]
then
    echo "Phone type must be nortel,cisco or nec"
    exit
fi

उपरोक्त कोड मेरे काम नहीं आया, इसलिए मैंने इसके बजाय यह कोशिश की:

if [ "$PHONE_TYPE" == "NORTEL" ] || [ "$PHONE_TYPE" == "NEC" ] ||
   [ "$PHONE_TYPE" == "CISCO" ]
then
    :        # do nothing
else
    echo "Phone type must be nortel,cisco or nec"
    exit
fi

क्या इस प्रकार के कार्य के लिए क्लीनर तरीके हैं?

जवाबों:


162

मुझे लगता है कि आप देख रहे हैं:

if [ "$PHONE_TYPE" != "NORTEL" ] && [ "$PHONE_TYPE" != "NEC" ] &&
   [ "$PHONE_TYPE" != "CISCO" ]

इन समकक्षों के नियमों को डी मॉर्गन के नियम कहा जाता है और आपके मामले में इसका मतलब है:

not(A || B || C) => not(A) && not(B) && not (C)

बूलियन ऑपरेटर या और में परिवर्तन पर ध्यान दें।

जबकि आपने करने की कोशिश की:

not(A || B || C) => not(A) || not(B) || not(C)

जो स्पष्ट रूप से काम नहीं करता है।


28

बहुत छोटा रास्ता होगा:

if [[ ! $PHONE_TYPE =~ ^(NORTEL|NEC|CISCO)$ ]]; then 
  echo "Phone type must be nortel, cisco or nec."
fi
  • ^ - लाइन की शुरुआत में एक मैच शुरू करने के लिए
  • $ - लाइन के अंत से मिलान करने के लिए
  • =~ - बैश के बिल्ट-इन नियमित अभिव्यक्ति तुलना ऑपरेटर

2
मुझे लगता है कि होना चाहिएif [[ ! $PHONE_TYPE =~ ^(NORTEL|NEC|CISCO)$ ]]; then
मिलान Simek

12

अच्छे उत्तर, और एक अमूल्य पाठ;) केवल एक नोट के साथ पूरक करना चाहते हैं।

किस प्रकार का परीक्षण उपयोग करना है यह कोड, संरचना, परिवेश आदि पर अत्यधिक निर्भर है।

एक विकल्प के caseरूप में एक स्विच या बयान का उपयोग किया जा सकता है:

case "$PHONE_TYPE" in
"NORTEL"|"NEC"|"CISCO")
    echo "OK"
    ;;
*)
    echo "Phone type must be nortel,cisco or nec"
    ;;
esac

दूसरे नोट के रूप में आपको ऊपरी-केस चर नामों का उपयोग करके सावधान रहना चाहिए। यह सिस्टम द्वारा शुरू किए गए चर के बीच टकराव को रोकने के लिए है, जो लगभग हमेशा सभी ऊपरी मामला है। इस प्रकार के $phone_typeबजाय $PHONE_TYPE

हालांकि वह एक सुरक्षित है, यदि आपको सभी ऊपरी मामलों का उपयोग करने की आदत है, तो एक दिन आप कह सकते हैं IFS="boo"और आप चोट की दुनिया में हैं।

इससे यह पता लगाना भी आसान हो जाएगा कि कौन सी जगह क्या है।

नहीं है , लेकिन दृढ़ता से विचार करना होगा।


यह संभवतः किसी समारोह के लिए एक अच्छा उम्मीदवार भी है। यह ज्यादातर कोड को पढ़ने और बनाए रखने में आसान बनाता है। उदाहरण के लिए:

valid_phone_type()
{
    case "$1" in
    "NORTEL"|"NEC")
        return 0;;
    *)
        echo "Model $1 is not supported"
        return 1;;
    esac
}

if ! valid_phone_type "$phone_type"; then
    echo "Bye."
    exit 1
fi

9

आपको ओआरएस का उपयोग करना चाहिए, न कि ओआरएस का।

if [ "$PHONE_TYPE" != "NORTEL" ] && [ "$PHONE_TYPE" != "NEC" ] && [ "$PHONE_TYPE" != "CISCO" ]
then

या

if [ "$PHONE_TYPE" != "NORTEL" -a "$PHONE_TYPE" != "NEC" -a "$PHONE_TYPE" != "CISCO" ]
then

1

उपरोक्त उत्तर को सही करने के लिए (जैसा कि मैं अभी तक टिप्पणी नहीं कर सकता):

PHONE_TYPE="NORTEL"
if [[ $PHONE_TYPE =~ ^(NORTEL|NEC|CISCO|SPACE TEL)$ ]]; then 
  echo "Phone type accepted."
else
  echo "Error! Phone type must be NORTEL, CISCO or NEC."
fi

कृपया ध्यान दें कि = ~ के इस उपयोग के लिए आपको कम से कम 4 bash की आवश्यकता है।
यह bash 3 में काम नहीं करता है।

मैंने एमएस विंडोज 7 पर बैश 4.3.46 (ठीक काम करता है) और 3.1.17 का उपयोग करके परीक्षण किया (काम नहीं किया)

= ~ का LHS उद्धरणों में होना चाहिए। ऊपर, PHONE_TYPE = "स्पेस टेली" भी मेल खाएगा।


0

इसके बजाय [[का उपयोग करें

if [[ "$PHONE_TYPE" != "NORTEL" ]] || [[ "$PHONE_TYPE" != "NEC" ]] || 
   [[ "$PHONE_TYPE" != "CISCO" ]]
then
echo "Phone type must be nortel,cisco or nec"
exit 1
fi

2
यह, ज़ाहिर है, गलत है। [[बनाम [तर्क बंद होने में मदद नहीं करता है।
ilkachachu

0

सिर्फ @ 0x80 समाधान पर आधारित एक भिन्नता प्रस्ताव:

# define phone brand list
phoneBrandList=" NORTEL NEC CISCO" ## separator is space with an extra space in first place

# test if user given phone is contained in the list
if [[ ${phoneBrandList} =~ (^|[[:space:]])"${userPhoneBrand}"($|[[:space:]]) ]]; then
    echo "found it !"
fi
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.