शेल स्क्रिप्ट में केस की असंवेदनशील तुलना


129

==ऑपरेटर खोल स्क्रिप्ट में दो स्ट्रिंग तुलना करने के लिए प्रयोग किया जाता है। हालांकि, मैं मामले की अनदेखी करने वाले दो तारों की तुलना करना चाहता हूं, यह कैसे किया जा सकता है? क्या इसके लिए कोई मानक आदेश है?

जवाबों:


72

अगर आपके पास बैश है

str1="MATCH"
str2="match"
shopt -s nocasematch
case "$str1" in
 $str2 ) echo "match";;
 *) echo "no match";;
esac

अन्यथा, आपको हमें यह बताना चाहिए कि आप किस शेल का उपयोग कर रहे हैं।

वैकल्पिक, awk का उपयोग करना

str1="MATCH"
str2="match"
awk -vs1="$str1" -vs2="$str2" 'BEGIN {
  if ( tolower(s1) == tolower(s2) ){
    print "match"
  }
}'

32
ifबयानों का उपयोग करते हुए तार की तुलना करने वाले किसी के लिए , shoptदृष्टिकोण को सिंगल-ब्रैकेट [[ ]]फॉर्म के बजाय सशर्त के डबल-ब्रैकेट फॉर्म का उपयोग करने की आवश्यकता होती है [ ]। यह भी देखें: gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html
indiv

3
प्रश्न इंगित करता है कि ==दो तारों की तुलना करने के लिए उपयोग किया जाता है, लेकिन प्रतिक्रिया एक caseबयान का उपयोग करके मामले-असंवेदनशील तुलना को प्रदर्शित करती है । आश्वासन देते हुए, shoptसमाधान भी केस-संवेदी के उपयोग में सक्षम बनाता है ==, =~अन्य स्ट्रिंग तुलना ऑपरेटर, और।
तरणाकी

7
shopt -u nocasematchबैश के डिफॉल्ट को वापस करने के लिए तुलना किए जाने के बाद निष्पादित करने के लिए संभवतः बुद्धिमान ।
ओहद श्नाइडर

6
nocasematchसेटिंग को सहेजने और पुनर्स्थापित करने के लिए सबसे अच्छा है । साथ यह पकड़ो SHELLNOCASEMATCH=`shopt -p nocasematch`तो साथ इसे बदलने shopt -s nocasematchऔर एक बार किया, साथ इसे फिर से स्थापित$SHELLNOCASEMATCH
Urhixidur

2
बेहतर अभी भी: SHELLNOCASEMATCH=$(shopt -p nocasematch; true)क्योंकि shopt -pविकल्प सेट नहीं होने पर कोड 1 के साथ बाहर निकल जाएगा, और इससे स्क्रिप्ट set -eप्रभाव में आ सकती है।
वी आर ऑल मोनिका

158

बैश में, आप किसी स्ट्रिंग को सभी लोअर / अपर-केस में संशोधित करने के लिए पैरामीटर विस्तार का उपयोग कर सकते हैं:

var1=TesT
var2=tEst

echo ${var1,,} ${var2,,}
echo ${var1^^} ${var2^^}

14
कम से कम एक उत्तर जो दुकान विकल्प का अर्थ नहीं करता है। तो आप दो स्ट्रिंग अनदेखी मामले की तुलना कर सकते हैं और एक ही परीक्षण में, मामले के साथ दो अन्य की तुलना कर सकते हैं। धन्यवाद
jehon

37
क्या यह बाश 4 में नया है? कम से कम बैश 3.2.51 में (OS X 10.9 में प्रयुक्त) यह काम नहीं करता है - पहला echoकथन परिणाम में है:-bash: ${var1,,}: bad substitution
फेलिक्स रब

1
इस तरह के मामले-असंवेदनशील तुलना कार्यान्वयन स्थानीयकरण के मुद्दों (जैसे तुर्की I समस्या) से ग्रस्त हैं। मुझे नहीं पता कि कैसे shopt -s nocasematchलागू किया जाता है, लेकिन आमतौर पर ऐसे "भाषा-स्तर" समाधान इसे सही ढंग से संभालते हैं।
ओहद श्नाइडर

5
@Ohad श्नाइडर, तुर्की स्थानीयकरण समस्याओं के बारे में तुर्क चिंता करते हैं, मैं सिर्फ स्ट्रिंग मैच के लिए एक त्वरित और कारगर तरीका की जरूरत है और इस huuuuuge अंतर से केक ले जाता है
Niken

1
macOS उपयोगकर्ता, अपना बैश संस्करण अपग्रेड करें। तुम्हारा इस बिंदु से एक दशक से अधिक पुराना है। itnext.io/upmission-bash-on-macos-7138bd1066ba
जेसन कार्टर

114

ये सभी उत्तर ऐसा करने के सबसे आसान और त्वरित तरीके को अनदेखा करते हैं (जब तक आपके पास बैश 4 है):

if [ "${var1,,}" = "${var2,,}" ]; then
  echo ":)"
fi

आप जो कुछ भी कर रहे हैं, वह परिणामों को कम करने और तुलना करने के लिए दोनों तारों को परिवर्तित कर रहा है।


6
यह केवल बैश 4 या नए में उपलब्ध है (उदाहरण के लिए Mac OS X 10.11 पर नहीं)
d4Rk

8
@ d4Rk यही कारण है कि मेरे उत्तर का पहला वाक्य "जब तक आपके पास बैश 4 है"। यह कहते हुए कि, बैश 4 इस टिप्पणी को लिखने के समय सात वर्षों से अधिक समय से बाहर है, और मेरे अपने ओएस एक्स इंस्टाल ने इसे लगभग लंबे समय तक रखा है।
दंगा

@ बहुत खेद है, ध्यान नहीं दिया कि पहली जगह में। मुझे पता है कि आप ओएस एक्स पर जो भी चाहते हैं उसे इंस्टॉल कर सकते हैं, लेकिन डिफ़ॉल्ट 3.2 है और जैसा कि मेरी स्क्रिप्ट को अलग-अलग मैक पर भी चलना चाहिए, यह वास्तव में मेरे लिए कोई विकल्प नहीं है।
d4Rk

2
@ d4Rk यह समझ में आता है - यदि आपको वास्तव में पोर्टेबिलिटी की गारंटी देने की आवश्यकता है, तो मैं POSIX शेल मानक से चिपके रहने का सुझाव दूंगा, क्योंकि आपको कुछ मामलों में बिल के किसी भी संस्करण को खोजने की गारंटी नहीं है।
दंगा

1
यही वह है जिसकी तलाश में मैं हूं। अधिक होना चाहिए =)
रॉबिन विंसलो

39

Nocasematch की स्थिति को बचाएं (यदि कोई अन्य कार्य अक्षम होने के आधार पर है):

local orig_nocasematch=$(shopt -p nocasematch)
shopt -s nocasematch
[[ "foo" == "Foo" ]] && echo "match" || echo "notmatch"
$orig_nocasematch

नोट: localयदि यह किसी फ़ंक्शन के अंदर है तो ही उपयोग करें ।


4
नाइस क्योंकि caseस्टेटमेंट (उन में घोस्टडॉग के जवाब सहित) हमेशा मेरी त्वचा को क्रॉल बना देंगे
सेलेडनीडे जूल

15

एक तरीका यह होगा कि दोनों तारों को ऊपरी या निचले हिस्से में बदला जाए:

test $(echo "string" | /bin/tr '[:upper:]' '[:lower:]') = $(echo "String" | /bin/tr '[:upper:]' '[:lower:]') && echo same || echo different

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

echo "string" | grep -qi '^String$' && echo same || echo different

मैं प्रयोग किया जाता trअल्पाइन (जो प्रदान करता है के आधार पर मेरे डोकर-ized अनुप्रयोगों में विधि shके माध्यम से busybox)। धन्यवाद।
एमएक्सवेस्ट

7

कोर्न शेल के लिए, मैं टाइपसेट बिल्ट-इन कमांड (लो-केस के लिए -l और अपर-केस के लिए -u) का उपयोग करता हूं।

var=True
typeset -l var
if [[ $var == "true" ]]; then
    print "match"
fi

2
जाग या किसी अन्य प्रक्रिया को शुरू करने की तुलना में प्रदर्शन के मामले में यह बेहतर है।
एलेक्स

1
बैश में, डिक्लेयर-एल या -यू का उपयोग विशेषताओं को सेट करने के लिए किया जा सकता है।
भारत

5

बहुत आसान है अगर आप केस-असंवेदनशील लाइन की तुलना करने के लिए fgrep करते हैं:

str1="MATCH"
str2="match"

if [[ $(fgrep -ix $str1 <<< $str2) ]]; then
    echo "case-insensitive match";
fi

इसके if fgrep -qix -- "$str1" <<<"$str2"; thenबजाय उपयोग करना बेहतर होगा ।

3

यहाँ tr का उपयोग कर मेरा समाधान है:

var1=match
var2=MATCH
var1=`echo $var1 | tr '[A-Z]' '[a-z]'`
var2=`echo $var2 | tr '[A-Z]' '[a-z]'`
if [ "$var1" = "$var2" ] ; then
  echo "MATCH"
fi

3

grepएक -iझंडा होता है, जिसका अर्थ होता है कि मामला असंवेदनशील है, इसलिए इसे आपको यह बताने के लिए कहें कि क्या var2 var1 में है।

var1=match 
var2=MATCH 
if echo $var1 | grep -i "^${var2}$" > /dev/null ; then
    echo "MATCH"
fi

3
var2 में कोई regex विशेष वर्ण हैं, तो काम नहीं करेगा।
हर्षित

3

के लिए zshवाक्य रचना थोड़ा अलग है, लेकिन अभी भी यहाँ सबसे जवाब तुलना में कम है:

> str1='mAtCh'
> str2='MaTcH'
> [[ "$str1:u" = "$str2:u" ]] && echo 'Strings Match!'
Strings Match!
>

यह तुलना करने से पहले दोनों तारों को अपरकेस में बदल देगा।


एक अन्य विधि का उपयोग करता है zsh है globbing flags, जो हमें सीधे iग्लोब ध्वज का उपयोग करके केस-असंवेदनशील मिलान का उपयोग करने की अनुमति देता है :

setopt extendedglob
[[ $str1 = (#i)$str2 ]] && echo "Match success"
[[ $str1 = (#i)match ]] && echo "Match success"


1

मैं इस महान ब्लॉग / ट्यूटोरियल / जो भी मामला संवेदनशील पैटर्न से निपटने के बारे में आया था । निम्नलिखित तीन विधियों को उदाहरणों के साथ विवरण में समझाया गया है:

1. tr कमांड का उपयोग करके पैटर्न को लोअरकेस में बदलें

opt=$( tr '[:upper:]' '[:lower:]' <<<"$1" )
case $opt in
        sql)
                echo "Running mysql backup using mysqldump tool..."
                ;;
        sync)
                echo "Running backup using rsync tool..."
                ;;
        tar)
                echo "Running tape backup using tar tool..."
                ;;
        *)
                echo "Other options"
                ;;
esac

2. केस पैटर्न के साथ रेगेक्स का उपयोग करें

opt=$1
case $opt in
        [Ss][Qq][Ll])
                echo "Running mysql backup using mysqldump tool..."
                ;;
        [Ss][Yy][Nn][Cc])
                echo "Running backup using rsync tool..."
                ;;
        [Tt][Aa][Rr])
                echo "Running tape backup using tar tool..."
                ;;
        *)
                echo "Other option"
                ;;
esac

3. nocasematch चालू करें

opt=$1
shopt -s nocasematch
case $opt in
        sql)
                echo "Running mysql backup using mysqldump tool..."
                ;;
        sync)
                echo "Running backup using rsync tool..."
                ;;
        tar)
                echo "Running tape backup using tar tool..."
                ;;
        *)
                echo "Other option"
                ;;
esac

shopt -u nocasematch
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.