कैसे जांचा जाए कि स्ट्रिंग में बैश में स्ट्रिंग है या नहीं


2564

मेरे पास बैश में एक स्ट्रिंग है:

string="My string"

यदि यह एक और स्ट्रिंग है तो मैं कैसे परीक्षण कर सकता हूं?

if [ $string ?? 'foo' ]; then
  echo "It's there!"
fi

??मेरा अज्ञात संचालक कहां है क्या मैं इको और का उपयोग करता हूं grep?

if echo "$string" | grep 'foo'; then
  echo "It's there!"
fi

यह थोड़ा अनाड़ी लगता है।


4
नमस्ते, अगर खाली तार झूठ हैं, तो आप इसे अनाड़ी क्यों मानते हैं? यह एकमात्र तरीका था जिसने प्रस्तावित समाधानों के बावजूद मेरे लिए काम किया।
ericson.cepeda

1
आप exprयहां कमांड का उपयोग कर सकते हैं
cli__

4
यहाँ
पॉज़िक्स

जवाबों:


3646

यदि आप डबल ब्रैकेट का उपयोग करते हैं, तो आप केस स्टेटमेंट के बाहर भी मार्कस के उत्तर (* वाइल्डकार्ड) का उपयोग कर सकते हैं :

string='My long string'
if [[ $string == *"My long"* ]]; then
  echo "It's there!"
fi

ध्यान दें कि सुई स्ट्रिंग में रिक्त स्थान को दोहरे उद्धरण चिह्नों के बीच रखा *जाना चाहिए , और वाइल्डकार्ड बाहर होना चाहिए। यह भी ध्यान दें कि एक साधारण तुलना ऑपरेटर का उपयोग किया जाता है (यानी ==), रेगेक्स ऑपरेटर नहीं =~


126
यह भी ध्यान दें कि आप परीक्षण में केवल =! पर स्विच करके तुलना को उलट सकते हैं। जवाब के लिए धन्यवाद!
क्विन टेलर

63
@ जोंक: आपको शेबंग की याद आ रही है या हो सकती है #!/bin/sh#!/bin/bashइसके बजाय कोशिश करें ।
अगली सूचना तक रोक दिया गया।

10
कोष्ठक और सामग्री के बीच एक स्थान छोड़ दें।
पॉल प्राइस

17
आपको [[]] के अंदर चर को उद्धृत करने की आवश्यकता नहीं है। यह भी काम करेगा: [[$ string == $ सुई ]] && प्रतिध्वनि मिली
Orwellophile

12
@Orwellophile सावधान! आप पहले तर्क में केवल दोहरे उद्धरण चिह्नों को छोड़ सकते हैं [[। देखें ideone.com/ZSy1gZ
nyuszika7h

611

यदि आप रेगेक्स दृष्टिकोण पसंद करते हैं:

string='My string';

if [[ $string =~ "My" ]]
then
   echo "It's there!"
fi

2
एक bash स्क्रिप्ट में egrep regex को बदलना पड़ा, यह पूरी तरह से काम करता है!
ब्लास्ट_हार्डीज़

114
=~ऑपरेटर पहले से ही एक मैच के लिए पूरी स्ट्रिंग खोज; .*के यहां बाहरी हैं। इसके अलावा, उद्धरण आम तौर पर बैकस्लैश के लिए बेहतर होते हैं:[[ $string =~ "My s" ]]
bukzor

16
@bukzor कोट्स ने यहां बैश 3.2+: tiswww.case.edu/php/chet/bash/FAQ के रूप में काम करना बंद कर दिया E14)। शायद एक चर (उद्धरणों का उपयोग करके) को असाइन करना सबसे अच्छा है, फिर तुलना करें। इस तरह:re="My s"; if [[ $string =~ $re ]]
15:15

36
टेस्ट करें अगर इसमें स्ट्रिंग नहीं है: if [[ ! "abc" =~ "d" ]]यह सच है।
क्रिशवेबडेव

1
ध्यान दें कि परीक्षण जिस क्रम में होता है वह मायने रखता है। कोड की निम्नलिखित पंक्ति का आउटपुट आगे होगा 2.number=2; if [[ "1, 2, 4, 5" = *${number}* ]]; then echo forward $number; fi; if [[ *${number}* = "1, 2, 4, 5" ]]; then echo backwards $number; fi;
डौवे वैन डेर लीस्ट

356

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

case "$string" in 
  *foo*)
    # Do stuff
    ;;
esac

76
यह संभवतः सबसे अच्छा समाधान है क्योंकि यह पॉज़िक्स के गोले से पोर्टेबल है। (उर्फ नो बाशिज़)
टेक्नोसॉरस

25
@technosaurus मुझे एक प्रश्न पर "बैशवाद" की आलोचना करने के बजाय यह अजीब लगता है कि केवल बैश टैग है :)
PP

39
@PP यह अधिक आलोचना नहीं है क्योंकि अधिक सीमित समाधान पर अधिक सार्वभौमिक समाधान की प्राथमिकता है। कृपया विचार करें कि, वर्षों बाद, लोग (मेरे जैसे) इस उत्तर को देखने के लिए रुकेंगे और मूल प्रश्न की तुलना में व्यापक दायरे में उपयोगी एक को पाकर प्रसन्न हो सकते हैं। जैसा कि वे ओपन सोर्स की दुनिया में कहते हैं: "पसंद अच्छी है!"
कार्ल स्मोत्रिकज़

2
@technosaurus, FWIW [[ $string == *foo* ]]कुछ POSIX अनुरूप श संस्करणों (जैसे /usr/xpg4/bin/shसोलारिस 10) और ksh (> = 88) में काम करता है
maxschlepzig

3
बिजीबॉक्स ऐश में तारांकन संभालती नहीं है [[... केस-स्विच ने काम किया!
रे फॉस

232

stringContain वेरिएंट (संगत या मामला स्वतंत्र)

जैसा कि ये स्टैक ओवरफ्लो उत्तर ज्यादातर बैश के बारे में बताते हैं , मैंने इस पोस्ट के बहुत नीचे एक केस बैश स्वतंत्र पोस्ट किया है ...

वैसे भी, वहाँ मेरा है

संगत जवाब

चूंकि बैश-विशिष्ट विशेषताओं का उपयोग करके पहले से ही बहुत सारे उत्तर हैं, इसलिए व्यस्त बॉक्स की तरह खराब-चित्रित शेल के तहत काम करने का एक तरीका है :

[ -z "${string##*$reqsubstr*}" ]

व्यवहार में, यह दे सकता है:

string='echo "My string"'
for reqsubstr in 'o "M' 'alt' 'str';do
  if [ -z "${string##*$reqsubstr*}" ] ;then
      echo "String '$string' contain substring: '$reqsubstr'."
    else
      echo "String '$string' don't contain substring: '$reqsubstr'."
    fi
  done

यह बैश, डैश , कॉर्नशेल ( ksh) और ऐश (बिजीबॉक्स) के तहत परीक्षण किया गया था , और परिणाम हमेशा:

String 'echo "My string"' contain substring: 'o "M'.
String 'echo "My string"' don't contain substring: 'alt'.
String 'echo "My string"' contain substring: 'str'.

एक समारोह में

जैसा कि @EeroAaltonen द्वारा पूछा गया है, यहां एक ही डेमो का एक संस्करण है, जो एक ही गोले के तहत परीक्षण किया गया है:

myfunc() {
    reqsubstr="$1"
    shift
    string="$@"
    if [ -z "${string##*$reqsubstr*}" ] ;then
        echo "String '$string' contain substring: '$reqsubstr'.";
      else
        echo "String '$string' don't contain substring: '$reqsubstr'."
    fi
}

फिर:

$ myfunc 'o "M' 'echo "My String"'
String 'echo "My String"' contain substring 'o "M'.

$ myfunc 'alt' 'echo "My String"'
String 'echo "My String"' don't contain substring 'alt'.

सूचना: आपको उद्धरणों और / या दोहरे उद्धरणों से बचना होगा

$ myfunc 'o "M' echo "My String"
String 'echo My String' don't contain substring: 'o "M'.

$ myfunc 'o "M' echo \"My String\"
String 'echo "My String"' contain substring: 'o "M'.

साधारण कार्य

यह बिज़ीबॉक्स, डैश, और निश्चित रूप से बैश के तहत परीक्षण किया गया था:

stringContain() { [ -z "${2##*$1*}" ]; }

तो अब:

$ if stringContain 'o "M3' 'echo "My String"';then echo yes;else echo no;fi
no
$ if stringContain 'o "M' 'echo "My String"';then echo yes;else echo no;fi
yes

... या यदि सबमिट किया गया स्ट्रिंग खाली हो सकता है, जैसा कि @Sjlver द्वारा बताया गया है, तो फ़ंक्शन बन जाएगा:

stringContain() { [ -z "${2##*$1*}" ] && [ -z "$1" -o -n "$2" ]; }

या एड्रियन गुंटर की टिप्पणी के अनुसार , -oस्विच से बचें :

stringContain() { [ -z "${2##*$1*}" ] && { [ -z "$1" ] || [ -n "$2" ];};}

अंतिम (सरल) फ़ंक्शन:

और उन्हें संभावित रूप से जल्दी बनाने के लिए परीक्षणों में प्रवेश करना:

stringContain() { [ -z "$1" ] || { [ -z "${2##*$1*}" ] && [ -n "$2" ];};}

खाली तारों के साथ:

$ if stringContain '' ''; then echo yes; else echo no; fi
yes
$ if stringContain 'o "M' ''; then echo yes; else echo no; fi
no

केस स्वतंत्र (केवल बैश!)

मामले की देखभाल के बिना स्ट्रिंग्स के परीक्षण के लिए, बस प्रत्येक स्ट्रिंग को लोअर केस में बदलें:

stringContain() {
    local _lc=${2,,}
    [ -z "$1" ] || { [ -z "${_lc##*${1,,}*}" ] && [ -n "$2" ] ;} ;}

चेक:

stringContain 'o "M3' 'echo "my string"' && echo yes || echo no
no
stringContain 'o "My' 'echo "my string"' && echo yes || echo no
yes
if stringContain '' ''; then echo yes; else echo no; fi
yes
if stringContain 'o "M' ''; then echo yes; else echo no; fi
no

1
यह और भी बेहतर होगा, अगर आप इसे किसी फंक्शन में लगाने के लिए कोई तरीका निकाल सकते हैं।
Eero Aaltonen

2
@EeroAaltonen आपको मेरा (नया जोड़ा) फ़ंक्शन कैसे पता चलेगा?
एफ। होरी

2
मुझे पता है! खोजो। -नाम "*" | xargs grep "myfunc" 2> / dev / null
अंडेमट्टर्स

6
यह अद्भुत है क्योंकि यह बहुत संगत है। एक बग, हालांकि: यह काम नहीं करता है अगर हेस्टैक स्ट्रिंग खाली है। सही संस्करण string_contains() { [ -z "${2##*$1*}" ] && [ -n "$2" -o -z "$1" ]; } एक अंतिम विचार होगा: क्या खाली स्ट्रिंग में खाली स्ट्रिंग होती है? चीजों के ऊपर संस्करण हां ( -o -z "$1"भाग के कारण)।
शाल्वर

3
+1। बहुत अच्छा! मेरे लिए मैंने ऑर्डर स्ट्रिंग परिवर्तित किया है () {[-z "$ {1 ## * $ 2 *}"] && [-z "$ 2" -o -n "$ 1"]; }; "खोजें जहां" "क्या खोजें"। बिजीबॉक्स में काम करें। ऊपर दिए गए स्वीकार किए गए उत्तर व्यस्त बॉक्स में काम नहीं करते हैं।
user3439968

148

आपको याद रखना चाहिए कि शेल स्क्रिप्टिंग भाषा से कम है और कमांड का संग्रह अधिक है। सहज रूप से आप सोचते हैं कि इस "भाषा" को आपको ifएक [या एक के साथ पालन ​​करने की आवश्यकता है [[। वे दोनों केवल आदेश हैं जो सफलता या विफलता का संकेत करते हुए एक निकास स्थिति लौटाते हैं (हर दूसरे आदेश की तरह)। इस कारण से मैं उपयोग करूँगा grep, और [कमांड नहीं ।

बस करो:

if grep -q foo <<<"$string"; then
    echo "It's there"
fi

अब जब आप ifकमांड के निकास की स्थिति का परीक्षण करने के बारे में सोच रहे हैं जो इसका अनुसरण करता है (अर्ध-बृहदान्त्र के साथ पूर्ण), तो उस स्ट्रिंग के स्रोत पर पुनर्विचार क्यों नहीं करें जिसे आप परीक्षण कर रहे हैं?

## Instead of this
filetype="$(file -b "$1")"
if grep -q "tar archive" <<<"$filetype"; then
#...

## Simply do this
if file -b "$1" | grep -q "tar archive"; then
#...

-qविकल्प के रूप में हम केवल वापसी कोड चाहते हैं, नहीं उत्पादन कुछ भी ग्रेप बनाता है। <<<शेल अगले शब्द का विस्तार करता है और इसे कमांड के इनपुट के रूप में उपयोग करता है, <<यहां दस्तावेज़ का एक-लाइन संस्करण (मुझे यकीन नहीं है कि यह मानक या बाशिस्म है)।


7
उन्हें यहां स्ट्रिंग्स कहा जाता है (3.6.7) मेरा मानना ​​है कि यह बैशवाद है
alex.pilon

10
एक प्रक्रिया प्रतिस्थापन का उपयोग भी कर सकता हैif grep -q foo <(echo somefoothing); then
लार्सर

ध्यान दें कि echoयदि आप एक चर पास कर रहे हैं, तो printf '%s' "$stringइसके बजाय , उपयोग करने योग्य है।
nyuszika7h

5
इसकी लागत बहुत महंगी है: grep -q foo <<<"$mystring"इम्पी 1 फोर्क करना और बैशीवाद है और echo $mystring | grep -q fooइम्पी 2 फोर्क्स (पाइप के लिए एक और रनिंग के लिए दूसरा /path/to/grep)
एफ। होरी

1
@BrunoBronosky echoबिना झंडे के अभी भी अप्रत्याशित पोर्टेबिलिटी की समस्या हो सकती है यदि तर्क स्ट्रिंग में बैकलैश अनुक्रम शामिल हैं। echo "nope\c"कुछ प्लेटफार्मों echo -e "nope"पर कुछ अन्य लोगों की तरह काम करने की उम्मीद है। printf '%s' "nope"बनामprintf '%s\n' 'nope\c'
ट्रिपल

92

स्वीकृत उत्तर सबसे अच्छा है, लेकिन चूंकि इसे करने का एक से अधिक तरीका है, यहाँ एक और उपाय है:

if [ "$string" != "${string/foo/}" ]; then
    echo "It's there!"
fi

${var/search/replace}है $varका पहला उदाहरण के साथ searchद्वारा बदल दिया replaceहै, अगर यह पाया जाता है (यह परिवर्तन नहीं करता है $var)। यदि आप fooकुछ भी नहीं बदलने की कोशिश करते हैं , और स्ट्रिंग बदल गई है, तो स्पष्ट रूप fooसे पाया गया था।


5
ऊपर दिए गए ephemient का समाधान:> `if [" $ string "! =" $ {string / foo /} "]; फिर गूंज "यह वहाँ है!" फ़ायबक्स के शेल ऐश का उपयोग करते समय फाई `उपयोगी है । स्वीकृत समाधान बिजीबॉक्स के साथ काम नहीं करता है क्योंकि कुछ बैश के नियमित भावों को लागू नहीं किया जाता है।
TPoschel

1
अंतर की असमानता। बहुत अजीब सोचा! मुझे यह पसंद है
nitinr708

1
जब तक आपका तार 'फू' नहीं है, हालांकि
जुलिमुस

मैंने स्वयं यही समाधान लिखा था (क्योंकि मेरे दुभाषिया शीर्ष उत्तर नहीं लेंगे) फिर एक बेहतर की तलाश में गया, लेकिन यह पाया गया!
बुविंजे

56

तो सवाल के बहुत सारे उपयोगी समाधान हैं - लेकिन जो सबसे तेज़ है / सबसे कम संसाधनों का उपयोग करता है?

इस फ्रेम का उपयोग करके बार-बार परीक्षण:

/usr/bin/time bash -c 'a=two;b=onetwothree; x=100000; while [ $x -gt 0 ]; do TEST ; x=$(($x-1)); done'

हर बार टेस्ट की जगह:

[[ $b =~ $a ]]           2.92 user 0.06 system 0:02.99 elapsed 99% CPU

[ "${b/$a//}" = "$b" ]   3.16 user 0.07 system 0:03.25 elapsed 99% CPU

[[ $b == *$a* ]]         1.85 user 0.04 system 0:01.90 elapsed 99% CPU

case $b in *$a):;;esac   1.80 user 0.02 system 0:01.83 elapsed 99% CPU

doContain $a $b          4.27 user 0.11 system 0:04.41 elapsed 99%CPU

(doContain F. Houri के उत्तर में था)

और गिगल्स के लिए:

echo $b|grep -q $a       12.68 user 30.86 system 3:42.40 elapsed 19% CPU !ouch!

तो साधारण प्रतिस्थापन विकल्प अनुमानित रूप से जीतता है कि क्या विस्तारित परीक्षण या एक मामले में। मामला पोर्टेबल है।

100000 ग्रीप्स तक पाइपिंग अनुमानित रूप से दर्दनाक है! आवश्यकता के बिना बाहरी उपयोगिताओं के उपयोग के बारे में पुराना नियम सही है।


4
नीच बेंचमार्क। मुझे इस्तेमाल करने के लिए मना लिया [[ $b == *$a* ]]
मैड फिजिसिस्ट

2
यदि मैं इसे सही ढंग से पढ़ रहा हूं, caseतो सबसे छोटी समग्र खपत के साथ जीतता है। आप $b in *$aहालांकि बाद एक तारांकन गायब कर रहे हैं । मुझे बग को ठीक करने की [[ $b == *$a* ]]तुलना में थोड़ा तेज परिणाम मिलता है case, लेकिन यह अन्य कारकों पर भी निर्भर कर सकता है।
ट्रिपलए

1
ideone.com/5roEVt में कुछ अतिरिक्त बग्स के साथ मेरा प्रयोग तय है और एक अलग परिदृश्य के लिए परीक्षण (जहां स्ट्रिंग वास्तव में लंबे स्ट्रिंग में मौजूद नहीं है)। परिणाम काफी हद तक समान हैं; [[ $b == *$a* ]]त्वरित है और caseलगभग उतना ही जल्दी है (और सुखद रूप से POSIX- संगत)।
ट्रिपलए

28

यह भी काम करता है:

if printf -- '%s' "$haystack" | egrep -q -- "$needle"
then
  printf "Found needle in haystack"
fi

और नकारात्मक परीक्षण है:

if ! printf -- '%s' "$haystack" | egrep -q -- "$needle"
then
  echo "Did not find needle in haystack"
fi

मुझे लगता है कि यह शैली बैश शेल की विशेषताओं पर थोड़ी अधिक क्लासिक - कम निर्भर है।

--तर्क शुद्ध POSIX व्यामोह, जैसे विकल्प, के समान इनपुट तार के खिलाफ की रक्षा के लिए इस्तेमाल किया है --abcया -a

नोट: एक तंग लूप में यह कोड आंतरिक बैश शेल विशेषताओं का उपयोग करने की तुलना में बहुत धीमा होगा , क्योंकि एक (या दो) अलग-अलग प्रक्रियाएं बनाई जाएंगी और पाइप के माध्यम से जुड़ी होंगी।


5
... लेकिन ओपी यह नहीं कहता कि कौन सा संस्करण बैश है; उदाहरण के लिए, पुराने बैश (जैसे सोलारिस में अक्सर होता है) में इन नए बैश फीचर शामिल नहीं हो सकते हैं। (मैं सोलारिस w / bash 2.0 पर इस सटीक समस्या (बैश पैटर्न को लागू नहीं किया गया) से मेल खाता हूं)
michael

2
echoprintf '%s' "$haystackइसके बजाय , आपको इसका उपयोग करना चाहिए ।
nyuszika7h

2
नहीं, बस echoपूरी तरह से बचने के बिना कुछ भी लेकिन शाब्दिक पाठ से बचना है कि एक के साथ शुरू नहीं होता है -। यह आपके लिए काम कर सकता है, लेकिन यह पोर्टेबल नहीं है। यहां तक ​​कि बैश की echoइच्छा अलग-अलग व्यवहार करेगी जो कि xpg_echoविकल्प सेट है। पुनश्च: मैं अपनी पिछली टिप्पणी में दोहरे उद्धरण को बंद करना भूल गया।
nyuszika7h

1
@kevinarpe मुझे यकीन नहीं है, के --लिए POSIX कल्पनाprintf में सूचीबद्ध नहीं है , लेकिन आप किसी printf '%s' "$anything"भी तरह का उपयोग करना चाहिए , अगर मुद्दों में से बचने के लिए $anythingएक %चरित्र होता है ।
nyuszika7h

1
@kevinarpe के आधार पर, यह शायद है।
nyuszika7h

21

बैश 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

उदाहरण 8, वाइल्डकार्ड मैच .ext (असंवेदनशील):

     if echo "$a" | egrep -iq "\.(mp[3-4]|txt|css|jpg|png)" ; then

का आनंद लें।


17

इस बारे में कैसा है:

text="   <tag>bmnmn</tag>  "
if [[ "$text" =~ "<tag>" ]]; then
   echo "matched"
else
   echo "not matched"
fi

2
= ~ रेगेक्सप मिलान के लिए है, इसलिए ओपी के उद्देश्य के लिए बहुत शक्तिशाली है।

16

जैसा कि पॉल ने अपने प्रदर्शन तुलना में उल्लेख किया है:

if echo "abcdefg" | grep -q "bcdef"; then
    echo "String contains is true."
else
    echo "String contains is not true."
fi

मार्कस द्वारा प्रदान किए गए उत्तर में 'केस "$ स्ट्रिंग" की तरह यह POSIX अनुपालन है , लेकिन केस स्टेटमेंट उत्तर की तुलना में इसे पढ़ना थोड़ा आसान है। यह भी ध्यान दें कि केस स्टेटमेंट का उपयोग करने की तुलना में यह बहुत धीमा होगा। जैसा कि पॉल ने बताया, इसे लूप में इस्तेमाल न करें।



9
[[ $string == *foo* ]] && echo "It's there" || echo "Couldn't find"

मैं जोड़ूंगा कि echo "Couldn't findअंत में बयान इन मिलान आदेशों के लिए 0 निकास स्थितियों को वापस करने के लिए एक अच्छी चाल है।
निकोडजिमेंज़

@nicodjimenez आप इस समाधान के साथ किसी भी अधिक बाहर निकलने की स्थिति को लक्षित नहीं कर सकते। बाहर निकलने की स्थिति स्टेटस मैसेज द्वारा निगल ली जाती है ...
जाहिद

1
यही मेरा मतलब है ... यदि आपके पास नहीं है || echo "Couldn't find"तो आप एक त्रुटि निकास स्थिति वापस कर देंगे यदि कोई मैच नहीं है, जो कि आप नहीं चाहते हैं कि क्या आप उदाहरण के लिए एक सीआई पाइपलाइन चला रहे हैं जहां आप सभी कमांड वापस करना चाहते हैं नॉन एरर एक्ज़िट स्टेटस
निकोडजिमेंज़

9

एक है:

[ $(expr $mystring : ".*${search}.*") -ne 0 ] && echo 'yes' ||  echo 'no'

2
exprउन स्विस-सेना-चाकू उपयोगिताओं में से एक है जो आमतौर पर आप जो कुछ भी करना चाहते हैं वह कर सकते हैं, एक बार जब आप इसे करने के तरीके का पता लगा लेते हैं, लेकिन एक बार कार्यान्वित होने के बाद, आप कभी भी याद नहीं रख सकते कि यह क्या कर रहा है या यह कैसे कर रहा है, इसलिए आप इसे फिर कभी न छूएं, और आशा करें कि यह कभी भी ऐसा करना बंद नहीं करता है जो यह कर रहा है।
माइकल

@AloisMahdal मैंने कभी भी वोट नहीं डाला, मैं सिर्फ इस बात पर ध्यान दे रहा हूं कि डाउनवोट्स क्यों दिए गए थे। एक सतर्क टिप्पणी। मैं exprदुर्लभ अवसर पर उपयोग करता हूं , जब पोर्टेबिलिटी बैश (उदाहरण के लिए, पुराने संस्करणों में असंगत व्यवहार), tr (असंगत हर जगह) या sed (कभी-कभी बहुत धीमी गति से) का उपयोग करने से रोकता है। लेकिन व्यक्तिगत अनुभव से, जब भी इन- exprधर्मों को फिर से पढ़ना , मुझे मैन पेज पर वापस जाना होगा। इसलिए, मैं सिर्फ इतना कहूंगा कि टिप्पणी के हर उपयोग पर expr...
माइकल

1
एक समय था जब आप सभी मूल बॉर्न शेल थे। इसमें कुछ आवश्यक सुविधाओं की कमी थी, इसलिए उन्हें प्रदर्शन करने के लिए उपकरण जैसे exprऔर testलागू किए गए थे। इस दिन और उम्र में, आमतौर पर बेहतर उपकरण होते हैं, उनमें से कई किसी भी आधुनिक शेल में निर्मित होते हैं। मुझे लगता testहै कि अभी भी वहां लटका हुआ है, लेकिन कोई भी गायब नहीं है expr
ट्रिपल

6

मुझे सेड पसंद है।

substr="foo"
nonsub="$(echo "$string" | sed "s/$substr//")"
hassub=0 ; [ "$string" != "$nonsub" ] && hassub=1

संपादित करें, तर्क:

  • स्ट्रिंग से प्रतिस्थापन के उदाहरण को हटाने के लिए sed का उपयोग करें

  • यदि नई स्ट्रिंग पुराने स्ट्रिंग से भिन्न होती है, तो विकल्प मौजूद होता है


2
कृपया कुछ स्पष्टीकरण जोड़ें। अंतर्निहित तर्क को लागू करना केवल कोड देने से ज्यादा महत्वपूर्ण है, क्योंकि यह ओपी और अन्य पाठकों को इसे ठीक करने में मदद करता है और इसी तरह के मुद्दों को स्वयं
Zulan

5

grep -q इस उद्देश्य के लिए उपयोगी है।

उसी का उपयोग कर awk:

string="unix-bash 2389"
character="@"
printf '%s' "$string" | awk -vc="$character" '{ if (gsub(c, "")) { print "Found" } else { print "Not Found" } }'

आउटपुट:

नहीं मिला

string="unix-bash 2389"
character="-"
printf '%s' "$string" | awk -vc="$character" '{ if (gsub(c, "")) { print "Found" } else { print "Not Found" } }'

आउटपुट:

मिल गया

मूल स्रोत: http://unstableme.blogspot.com/2008/06/bash-search-letter-in-string-awk.html


3
echoprintf '%s' "$string"इसके बजाय , आपको इसका उपयोग करना चाहिए । मैं उत्तर का संपादन कर रहा हूं क्योंकि उपयोगकर्ता अब मौजूद नहीं है।
nyuszika7h

किस तरह से echoपोर्टेबल नहीं है, @ nyuszika7h?
स्टारबिम्रेनबोलाब्स

5

मुझे इस कार्यशीलता की बहुत बार जरूरत पड़ी, इसलिए मैं अपने घर में बने शेल फ़ंक्शन .bashrcका उपयोग इस तरह से कर रहा हूं जो मुझे नाम याद रखने के लिए एक आसान के साथ जितनी बार आवश्यकता हो, इसका पुन: उपयोग करने की अनुमति देता है:

function stringinstring()
{
    case "$2" in
       *"$1"*)
          return 0
       ;;
    esac
    return 1
}

यह $string1कहने के लिए कि क्या (कहो, एबीसी ) में परीक्षण करना है $string2(कहो, 123abcABC ) मुझे केवल stringinstring "$string1" "$string2"वापसी मूल्य के लिए चलाने और जांचने की आवश्यकता है , उदाहरण के लिए

stringinstring "$str1" "$str2"  &&  echo YES  ||  echo NO

[["$ str" == $ पदार्थ ]] && इको YES || इको नं
ईलाइज़

मुझे पूरा यकीन है कि xहैक केवल बहुत पुराने गोले के लिए आवश्यक है ।
nyuszika7h

5

मेरी .bash_profile फ़ाइल और मैंने grep का उपयोग कैसे किया:

यदि PATH परिवेश चर में मेरी दो binनिर्देशिकाएँ शामिल हैं, तो उन्हें संलग्न न करें,

# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

U=~/.local.bin:~/bin

if ! echo "$PATH" | grep -q "home"; then
    export PATH=$PATH:${U}
fi

1
क्या यह एक उत्तर है?
कोडफोर्स

वोट दें। यह जानने की जहमत क्यों उठाते हैं कि ब्रेश कैसे करते हैं जब grep, कहीं अधिक शक्तिशाली होता है, उपलब्ध होने की संभावना से अधिक होता है। पैटर्न की सूची के विरुद्ध मिलान करके इसे थोड़ा और आगे बढ़ाएँ grep -q -E 'pattern1|...|patternN':।
मोहम्मद बन

4

यहां दिए गए प्रश्न के विस्तार में आप यह कैसे बता सकते हैं कि एक स्ट्रिंग में POSIX श में एक और स्ट्रिंग है? :

यह समाधान विशेष वर्णों के साथ काम करता है:

# contains(string, substring)
#
# Returns 0 if the specified string contains the specified substring,
# otherwise returns 1.
contains() {
    string="$1"
    substring="$2"

    if echo "$string" | $(type -p ggrep grep | head -1) -F -- "$substring" >/dev/null; then
        return 0    # $substring is in $string
    else
        return 1    # $substring is not in $string
    fi
}

contains "abcd" "e" || echo "abcd does not contain e"
contains "abcd" "ab" && echo "abcd contains ab"
contains "abcd" "bc" && echo "abcd contains bc"
contains "abcd" "cd" && echo "abcd contains cd"
contains "abcd" "abcd" && echo "abcd contains abcd"
contains "" "" && echo "empty string contains empty string"
contains "a" "" && echo "a contains empty string"
contains "" "a" || echo "empty string does not contain a"
contains "abcd efgh" "cd ef" && echo "abcd efgh contains cd ef"
contains "abcd efgh" " " && echo "abcd efgh contains a space"

contains "abcd [efg] hij" "[efg]" && echo "abcd [efg] hij contains [efg]"
contains "abcd [efg] hij" "[effg]" || echo "abcd [efg] hij does not contain [effg]"

contains "abcd *efg* hij" "*efg*" && echo "abcd *efg* hij contains *efg*"
contains "abcd *efg* hij" "d *efg* h" && echo "abcd *efg* hij contains d *efg* h"
contains "abcd *efg* hij" "*effg*" || echo "abcd *efg* hij does not contain *effg*"

परीक्षण contains "-n" "n"यहाँ काम नहीं करता है, क्योंकि एक विकल्प echo -nके -nरूप में निगल जाएगा ! इसके लिए एक लोकप्रिय फिक्स printf "%s\n" "$string"इसके बजाय उपयोग करना है।
joeytwiddle

पूरी तरह से, हल स्ट्रिंग स्ट्रिंग रिक्त स्थान
dengApro

4

चूंकि POSIX / BusyBox प्रश्न सही उत्तर (IMHO) प्रदान किए बिना बंद है, इसलिए मैं यहां एक उत्तर पोस्ट करूंगा।

सबसे छोटा संभव उत्तर है:

[ ${_string_##*$_substring_*} ] || echo Substring found!

या

[ "${_string_##*$_substring_*}" ] || echo 'Substring found!'

ध्यान दें कि डबल हैश है अनिवार्य कुछ गोले के साथ ( ash)। उपर्युक्त मूल्यांकन करेगा [ stringvalue ]जब प्रतिस्थापन नहीं मिला है। यह कोई त्रुटि नहीं देता है। जब प्रतिस्थापन पाया जाता है तो परिणाम खाली होता है और यह मूल्यांकन करता है [ ]। यह त्रुटि कोड 1 को फेंक देगा क्योंकि स्ट्रिंग पूरी तरह से प्रतिस्थापित किया गया है (के कारण)* ) है।

सबसे छोटा सामान्य वाक्यविन्यास:

[ -z "${_string_##*$_substring_*}" ] && echo 'Substring found!'

या

[ -n "${_string_##*$_substring_*}" ] || echo 'Substring found!'

और एक:

[ "${_string_##$_substring_}" != "$_string_" ] && echo 'Substring found!'

या

[ "${_string_##$_substring_}" = "$_string_" ] || echo 'Substring found!'

एकल बराबर संकेत पर ध्यान दें !



3

ओबश की कोशिश करें।

यह बैश 4 के लिए एक ओ-स्टाइल स्ट्रिंग लाइब्रेरी है। इसमें जर्मन ओमलैट्स के लिए समर्थन है। यह बाश में लिखा है।

कई कार्यों उपलब्ध हैं: -base64Decode, -base64Encode, -capitalize, -center, -charAt, -concat, -contains, -count, -endsWith, -equals, -equalsIgnoreCase, -reverse, -hashCode, -indexOf, -isAlnum, -isAlpha, -isAscii, -isDigit, -isEmpty, -isHexDigit, -isLowerCase, -isSpace, -isPrintable, -isUpperCase, -isVisible, -lastIndexOf, -length, -matches, -replaceAll, -replaceFirst, -startsWith, -substring, -swapCase, -toLowerCase, -toString, -toUpperCase, -trim, और -zfill

पर देखो होता है उदाहरण:

[Desktop]$ String a testXccc
[Desktop]$ a.contains tX
true
[Desktop]$ a.contains XtX
false

oobash Sourceforge.net पर उपलब्ध है


2

मैं इस फ़ंक्शन का उपयोग करता हूं (एक निर्भरता शामिल नहीं है लेकिन स्पष्ट है)। यह नीचे दिखाए गए परीक्षणों को पास करता है। यदि फ़ंक्शन एक मान> 0 लौटाता है, तो स्ट्रिंग पाया गया था। आप इसके बजाय आसानी से 1 या 0 वापस कर सकते हैं।

function str_instr {
   # Return position of ```str``` within ```string```.
   # >>> str_instr "str" "string"
   # str: String to search for.
   # string: String to search.
   typeset str string x
   # Behavior here is not the same in bash vs ksh unless we escape special characters.
   str="$(str_escape_special_characters "${1}")"
   string="${2}"
   x="${string%%$str*}"
   if [[ "${x}" != "${string}" ]]; then
      echo "${#x} + 1" | bc -l
   else
      echo 0
   fi
}

function test_str_instr {
   str_instr "(" "'foo@host (dev,web)'" | assert_eq 11
   str_instr ")" "'foo@host (dev,web)'" | assert_eq 19
   str_instr "[" "'foo@host [dev,web]'" | assert_eq 11
   str_instr "]" "'foo@host [dev,web]'" | assert_eq 19
   str_instr "a" "abc" | assert_eq 1
   str_instr "z" "abc" | assert_eq 0
   str_instr "Eggs" "Green Eggs And Ham" | assert_eq 7
   str_instr "a" "" | assert_eq 0
   str_instr "" "" | assert_eq 0
   str_instr " " "Green Eggs" | assert_eq 6
   str_instr " " " Green "  | assert_eq 1
}

दुविधा! निर्भरता क्या है ?
पीटर मोर्टेंसन

"Str_escape_special_characters" फ़ंक्शन। यह GitHub arcshell_str.sh फ़ाइल में है। arcshell.io आपको वहां मिलेगा।
एथन पोस्ट


0
msg="message"

function check {
    echo $msg | egrep [abc] 1> /dev/null

    if [ $? -ne 1 ];
    then 
        echo "found" 
    else 
        echo "not found" 
    fi
}

check

यह एक या बी या सी के किसी भी रोड़ा मिलेगा


0

सामान्य सुई हैस्टैक उदाहरण चर के साथ पीछा कर रहा है

#!/bin/bash

needle="a_needle"
haystack="a_needle another_needle a_third_needle"
if [[ $haystack == *"$needle"* ]]; then
    echo "needle found"
else
    echo "needle NOT found"
fi
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.