बश में तार की तुलना कैसे करें


957

मैं एक चर की तुलना स्ट्रिंग से कैसे कर सकता हूं (और यदि वे मेल खाते हैं तो कुछ करते हैं)?



जवाबों:


1372

अगर बयानों में चर का उपयोग करना

if [ "$x" = "valid" ]; then
  echo "x has the value 'valid'"
fi

आप कुछ जब वे मेल नहीं खाते करना चाहते हैं, की जगह =के साथ !=। आप उनके संबंधित प्रलेखन में स्ट्रिंग संचालन और अंकगणितीय संचालन के बारे में अधिक पढ़ सकते हैं ।

हम उद्धरणों का उपयोग क्यों करते हैं $x?

आप आस-पास के उद्धरण चाहते हैं $x, क्योंकि यदि यह खाली है, तो आपकी बैश स्क्रिप्ट का सिंटैक्स त्रुटि के रूप में नीचे देखा गया है:

if [ = "valid" ]; then

==ऑपरेटर के गैर-मानक उपयोग

ध्यान दें कि बैश के ==साथ समानता के लिए उपयोग करने की अनुमति देता है [, लेकिन यह मानक नहीं है

या तो पहले मामले का उपयोग करें जिसमें आसपास के उद्धरण $xवैकल्पिक हैं:

if [[ "$x" == "valid" ]]; then

या दूसरे मामले का उपयोग करें:

if [ "$x" = "valid" ]; then

12
यह कैसे अनपेक्षित ऑपरेटर त्रुटि में दिए गए स्वीकृत उत्तर से संबंधित है ? उपयोग करते समय मुझे वही त्रुटि मिली [ "$1" == "on" ]। इसे ["$ 1" = "पर" बदलने से समस्या हल हो गई।
पायोटर डोब्रोगोस्ट

78
रिक्त स्थान की आवश्यकता है।
TAAPSogeking

6
@ जॉनफिनेला बेश स्क्रिप्ट में लिखते समय, इसमें एक =और दो नहीं होना चाहिए ।
user13107

72
यह ध्यान देने योग्य हो सकता है कि आप उपयोग नहीं कर सकते [ $x -eq "valid" ]-eqपूर्णांक के लिए तुलना ऑपरेटर है, तार नहीं।
क्रेक

2
@ एलेक्स, किन मामलों में (यदि कभी हो) क्या मुझे पैटर्न का उपयोग करने की आवश्यकता है ["x$yes" == "xyes"], जो चर और स्ट्रिंग शाब्दिक दोनों के साथ उपसर्ग कर रहा है a x? क्या यह पुराने समय का अवशेष है या कुछ स्थितियों में इसकी वास्तव में आवश्यकता है?
लैंक्सक्स

142

या, यदि आपको अन्य खंड की आवश्यकता नहीं है:

[ "$x" == "valid" ] && echo "x has the value 'valid'"

71
और अगर आपको एक और क्लॉज़ की आवश्यकता है और एक पागल-लाइनर बनाना चाहते हैं: ["$ x" == "वैध"] && गूंज "वैध" || इको "अमान्य"
मैट व्हाइट

11
@MattWhite: यह आमतौर पर एक बुरा विचार है, जैसा कि echoविफल हो सकता है।
गनीउर_ग्निउरफ

1
यहां तक ​​कि थो गोचेचा भी दिखाई दे सकता है, जो मार्को && मैटव्हाइट दोनों से सुंदर और सुरुचिपूर्ण तरीके से हो
Deko

3
@gniourf_gniourf, कोई समस्या नहीं, उपयोग करें [ "$X" == "valid" ] || ( echo invalid && false ) && echo "valid"
12431234123412341234123 15

4
@ 12431234123412341234123 { echo invalid && false; }की तुलना में अधिक कुशल है ( echo invalid && false ), क्योंकि यह एक अनावश्यक उपधारा के लिए भुगतान करने से बचता है।
चार्ल्स डफी

84
a="abc"
b="def"

# Equality Comparison
if [ "$a" == "$b" ]; then
    echo "Strings match"
else
    echo "Strings don't match"
fi

# Lexicographic (greater than, less than) comparison.
if [ "$a" \< "$b" ]; then
    echo "$a is lexicographically smaller then $b"
elif [ "$a" \> "$b" ]; then
    echo "$b is lexicographically smaller than $a"
else
    echo "Strings are equal"
fi

टिप्पणियाँ:

  1. के बीच रिक्त स्थान ifऔर [और ]महत्वपूर्ण हैं
  2. >और <पुनर्निर्देशन ऑपरेटर तार के लिए \>और \<क्रमशः इसके साथ बच जाते हैं।

6
स्ट्रिंग वर्णमाला क्रम की तुलना के लिए धन्यवाद
shadi

मेरा मुद्दा यह था कि $aवास्तव में " "इसे स्ट्रिंग शाब्दिक मूल्य के हिस्से के रूप में घेर लिया गया था , इसलिए मुझे $bमूल्यों की तुलना करने के लिए बच चरित्र का उपयोग करना पड़ा । मैं इसे चलाने के बाद इसे खोजने में सक्षम था bash -x ./script.sh, -x ध्वज आपको प्रत्येक निष्पादन का मूल्य देखने की अनुमति देता है और डिबगिंग में मदद करता है।
शाहनवाज़खान

ध्यान दें कि वर्णमाला क्रम की तुलना POSIX- मानकीकृत नहीं है, इसलिए यह गैर-जीएनयू प्लेटफार्मों / गैर-बैश शेल पर काम करने की गारंटी नहीं है। केवल pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html पर ऑपरेशन पोर्टेबल होने की गारंटी है।
चार्ल्स डफी

62

वाइल्डकार्ड के उपयोग के साथ तार की तुलना करने के लिए

if [[ "$stringA" == *$stringB* ]]; then
  # Do something here
else
  # Do Something here
fi

12
यह महत्वपूर्ण है कि वाइल्डकार्ड का उपयोग केवल दाईं ओर किया जा सकता है! "वाइल्डकार्ड के आसपास गुमशुदगी पर भी ध्यान दें । (Btw: वाइल्डकार्ड के लिए +1)
Scz

6
विस्तार $stringB को उद्धृत किया जाना चाहिए (और संयोग से, बाएं हाथ की ओर को उद्धृत करने की आवश्यकता नहीं है) if [[ $stringA = *"$stringB"* ]]; then:।
गनीउर_ग्निउरफ

मैं फ़ाइलपथ में फ़ाइल नाम के लिए एक ही वाइल्डकार्ड तर्क का उपयोग करने की कोशिश कर रहा हूं। लेकिन यह मेरे लिए काम नहीं कर रहा है। यहां प्रदान किए गए सभी अलग-अलग वाइल्डकार्ड स्ट्रिंग्स की कोशिश की। लेकिन यह हमेशा दूसरे मामले में जाता है। स्ट्रिंग मेरे मामले में एक फ़ाइल पथ / tmp / फ़ाइल है और stringB "फ़ाइल" है।
बारिश

35

मुझे एक बिंदु पर टिप्पणी से असहमत होना है:

[ "$x" == "valid" ] && echo "valid" || echo "invalid"

नहीं, वह पागल नहीं है

यह सिर्फ एक के लिए लग रहा है, हम्म, uninitiated ...

यह एक भाषा के रूप में सामान्य पैटर्न का उपयोग करता है, एक तरह से;

और आपने भाषा सीखी।

दरअसल, यह पढ़कर अच्छा लगा

यह एक सरल तार्किक अभिव्यक्ति है, जिसमें एक विशेष भाग है: तर्क ऑपरेटरों का आलसी मूल्यांकन।

[ "$x" == "valid" ] && echo "valid" || echo "invalid"

प्रत्येक भाग एक तार्किक अभिव्यक्ति है; पहला सच या गलत हो सकता है, बाकी दो हमेशा सच होते हैं।

(
[ "$x" == "valid" ] 
&&
echo "valid"
)
||
echo "invalid"

अब, जब इसका मूल्यांकन किया जाता है, तो पहले जांच की जाती है। यदि यह गलत है, तो तर्क के दूसरे ऑपरेंड की तुलना में और इसके && बाद प्रासंगिक नहीं है। पहला सच नहीं है, इसलिए यह पहला और दूसरा सच नहीं हो सकता है।
अब, इस मामले में तर्क का पहला पक्ष या || असत्य है, लेकिन यह सच हो सकता है यदि दूसरा पक्ष - तीसरा भाग - सत्य है।

तो तीसरे भाग का मूल्यांकन किया जाएगा - मुख्य रूप से संदेश को साइड इफेक्ट के रूप में लिखना। (इसका 0सच के लिए परिणाम है, जिसका हम यहां उपयोग नहीं करते हैं)

अन्य मामले समान हैं, लेकिन सरल - और - मैं वादा करता हूँ! हैं - हो सकता है - पढ़ने में आसान!
(मेरे पास एक नहीं है, लेकिन मुझे लगता है कि ग्रे दाढ़ी के साथ एक यूनिक्स दिग्गज होने के नाते इससे बहुत मदद मिलती है।)


17
... && ... || ...आमतौर पर, (सभी इस समय के लिए खेद है बूढ़ा यूनिक्स अनुभवी, जहां आप जा चुके गलत) पर भ्रूभंग के रूप में यह शब्दार्थ के बराबर नहीं है है if ... then ... else ...। चिंता न करें, यह एक आम नुकसान है
ग्नौरफ_ग्निउरफ

6
@gniourf_gniourf ओपी गलत नहीं है - और न ही वे अज्ञानी हैं जैसा कि आप सुझाव देते हैं। ... && ... || ...एक पूरी तरह से मान्य पैटर्न और एक सामान्य बैश मुहावरा है। इसका उपयोग पूर्व ज्ञान (जो दर्शकों में शुरुआती हैं तो ध्यान में रखना अच्छा हो सकता है) लिखता है, लेकिन ओपी के पास यह साबित करने के लिए बाल हैं कि वे खुले मैनहोल कवर से कैसे बचें।
इबपा

3
@ebpa क्या होगा यदि कथन के बाद && गलत मान देता है, तो क्या वह कथन को आगे बढ़ाएगा? ? अगर ऐसा है तो गलत है और शायद यही बात है कि gnourf सुझाव दे रहा है
TSG

4
मुझे लगा कि प्रतिध्वनि केवल एक उदाहरण था। निम्नलिखित कथन && अभी भी गैर-शून्य मान लौटा सकता है
TSG

2
बैश नुकसान की लिंक पोस्ट करने के लिए @gniourf_gniourf +1! बहुत उपयोगी!
जगुआर

21

तुम भी उपयोग मामला / esac का उपयोग कर सकते हैं

case "$string" in
 "$pattern" ) echo "found";;
esac

यह साम्य है या सम्‍मिलित है?
ytpillai

@ytpillai, यह समतुल्यता है। ध्यान रखें कि आप पैटर्न को |पहले से अलग कर सकते हैं )inबयान के बराबर है thenमें ifबयान। आप तर्क कर सकते हैं कि यह पैटर्न की एक सूची पर काम करता है, जहां प्रत्येक सूची की अपनी घोषणा है कि क्या करना है, अगर आप पायथन से आते हैं। पसंद नहीं substring in string, बल्कि for item in list*यदि आप एक elseशर्त चाहते हैं तो अपने अंतिम विवरण के रूप में उपयोग करें । यह पहली मुठभेड़ पर लौटता है।
mazunki

18

निम्नलिखित स्क्रिप्ट लाइन द्वारा "टेस्टोथेरिस" लाइन नामक एक फ़ाइल से पढ़ती है और फिर प्रत्येक पंक्ति की तुलना एक साधारण स्ट्रिंग, विशेष पात्रों के साथ एक स्ट्रिंग और एक नियमित अभिव्यक्ति के साथ करती है। यदि यह मेल नहीं खाता है, तो स्क्रिप्ट लाइन प्रिंट करेगी, अन्यथा नहीं।

बाश में अंतरिक्ष इतना महत्वपूर्ण है। तो निम्नलिखित काम करेगा:

[ "$LINE" != "table_name" ] 

लेकिन निम्नलिखित नहीं होगा:

["$LINE" != "table_name"] 

तो कृपया का उपयोग करें:

cat testonthis | while read LINE
do
if [ "$LINE" != "table_name" ] && [ "$LINE" != "--------------------------------" ] && [[ "$LINE" =~ [^[:space:]] ]] && [[ "$LINE" != SQL* ]]; then
echo $LINE
fi
done

फ़ाइल के माध्यम से जाने के लिए इस दृष्टिकोण का उपयोग करें । यही है, अन्य चीजों के बीच UUoC को हटा दें।
फेडोरक्वी 'एसओ ने

यह महत्वपूर्ण नहीं है bashक्योंकि [यह वास्तव में एक बाहरी द्विआधारी है (जैसा कि which [कुछ पैदावार में होता है /usr/bin/[)
पैट्रिक बर्गनर

11

यदि इनपुट में केवल कुछ मान्य प्रविष्टियाँ हैं, तो मैं शायद regexp मैचों का उपयोग करूंगा। उदाहरण के लिए, केवल "प्रारंभ" और "स्टॉप" ही मान्य कार्य हैं।

if [[ "${ACTION,,}" =~ ^(start|stop)$ ]]; then
  echo "valid action"
fi

ध्यान दें कि मैं $ACTIONडबल अल्पविराम का उपयोग करके चर को कम करता हूं । यह भी ध्यान दें कि यह बहुत पुराने बेश संस्करणों पर काम नहीं करेगा।


9

बैश 4+ उदाहरण। नोट: शब्दों के रिक्त स्थान होने पर, उद्धरणों का उपयोग न करने से हमेशा बैश, IMO में उद्धरण होंगे।

यहाँ बश 4+ में कुछ उदाहरण दिए गए हैं:

उदाहरण 1, स्ट्रिंग में 'हाँ' के लिए जाँच करें (केस असंवेदनशील):

    if [[ "${str,,}" == *"yes"* ]] ;then

उदाहरण 2, स्ट्रिंग में 'हाँ' के लिए जाँच करें (केस असंवेदनशील):

    if [[ "$(echo "$str" | tr '[:upper:]' '[:lower:]')" == *"yes"* ]] ;then

उदाहरण 3, स्ट्रिंग में 'हाँ' के लिए जाँच करें (मामला संवेदनशील):

     if [[ "${str}" == *"yes"* ]] ;then

उदाहरण 4, स्ट्रिंग में 'हाँ' के लिए जाँच करें (मामला संवेदनशील):

     if [[ "${str}" =~ "yes" ]] ;then

उदाहरण 5, सटीक मिलान (मामला संवेदनशील):

     if [[ "${str}" == "yes" ]] ;then

उदाहरण 6, सटीक मिलान (केस असंवेदनशील):

     if [[ "${str,,}" == "yes" ]] ;then

उदाहरण 7, सटीक मिलान:

     if [ "$a" = "$b" ] ;then

का आनंद लें।


मेरे लिए (मैक GNU बैश संस्करण 4.4.12 (1) -release x86_64-apple-darwin17.0.0), मुझे इसका उपयोग करना है if [ "$a"="$b" ]या यह काम नहीं करता है ... बराबरी के चारों ओर रिक्त स्थान नहीं हो सकता
स्पेक्ट्रम

1

मैंने इसे इस तरह से किया जो बैश और डैश (श) के साथ संगत है :

testOutput="my test"
pattern="my"

case $testOutput in (*"$pattern"*)
    echo "if there is a match"
    exit 1
    ;;
(*)
   ! echo there is no coincidence!
;;esac

पूर्ववर्ती (बनाम इसका उपयोग न करने के बीच क्या अंतर है?
माज़ुन्की
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.