यदि स्ट्रिंग में एक स्ट्रिंग हो तो टेस्ट करें


40

मेरे पास कोड है

file="JetConst_reco_allconst_4j2t.png"
if [[ $file == *_gen_* ]];
then
    echo "True"
else
    echo "False"
fi

मैं परीक्षण करता हूं यदि file"जीन" शामिल है। आउटपुट "गलत" है। अच्छा!

समस्या यह है कि जब मैं एक चर के साथ "जीन" स्थानापन्न करता हूं testseq:

file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
if [[ $file == *_$testseq_* ]];
then
    echo "True"
else
    echo "False"
fi

अब आउटपुट "ट्रू" है। ऐसा कैसे हो सकता है? समस्या को कैसे ठीक करें?


जवाबों:


25

आपको $testseqनिम्न तरीकों में से एक के साथ चर को प्रक्षेपित करने की आवश्यकता है:

  • $file == *_"$testseq"_*(यहाँ $testseqएक निश्चित स्ट्रिंग के रूप में माना जाता है)

  • $file == *_${testseq}_*(यहाँ $testseqएक पैटर्न के रूप में माना जाता है)।

या _चर के नाम के तुरंत बाद चर के नाम के हिस्से के रूप में लिया जाएगा (यह एक चर नाम में एक वैध चरित्र है)।


सही उत्तर के रूप में यह ओपी पर लागू होता है, लेकिन w / o पोर्टेबल हो रहा है। (यह प्रदान किए गए उत्तर की आलोचना नहीं है, सिर्फ पाठकों के लिए एक चेतावनी है)। ;-)
Cbhihe

28

=~नियमित अभिव्यक्ति के नियम बनाने के लिए ऑपरेटर का उपयोग करें :

#!/bin/bash
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
if [[ $file =~ $testseq ]];
then
    echo "True"
else
    echo "False"
fi

इस तरह, यह करता है, तो तुलना करेंगे $fileहै $testseqइसकी सामग्री पर।

user@host:~$ ./string.sh
False

अगर मैं बदलता हूं testseq="Const":

user@host:~$ ./string.sh
True

लेकिन, इसके साथ सावधान रहें कि आप क्या खाते हैं $testseq। यदि इस पर स्ट्रिंग कुछ हद तक एक रेगेक्स ( [0-9]उदाहरण के लिए) का प्रतिनिधित्व करती है, तो "मैच" को ट्रिगर करने का अधिक मौका होता है।

संदर्भ :


20
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"

case "$file" in
    *_"$testseq"_*) echo 'True'  ;;
    *)              echo 'False'
esac

का उपयोग करते हुए case ... esacएक पोर्टेबल रास्ते में एक पैटर्न मैच प्रदर्शन करने के लिए सरल तरीके से एक है। यह अन्य भाषाओं में एक "स्विच" बयान के रूप में काम करता है ( bash, zsh, और ksh93भी आप करने की अनुमति देता गिरावट के माध्यम से विभिन्न असंगत तरीके में)। उपयोग किए जाने वाले पैटर्न मानक फ़ाइल नाम ग्लोबिंग पैटर्न हैं।

समस्या जो आप कर रहे हैं वह इस तथ्य के कारण है कि _एक चर नाम में एक मान्य वर्ण है। शेल इस प्रकार *_$testseq_*" *_चर के मूल्य के बाद $testseq_और एक *" के रूप में देखेंगे । चर $testseq_अपरिभाषित है, इसलिए इसे एक रिक्त स्ट्रिंग में विस्तारित किया जाएगा, और आप के साथ समाप्त होता है *_*, जो स्पष्ट रूप से $fileआपके पास मूल्य से मेल खाता है। आप कम से कम एक अंडरस्कोर में Trueफ़ाइल नाम के रूप में लंबे समय तक प्राप्त करने की उम्मीद कर सकते हैं $file

चर के नाम को ठीक से परिसीमन करने के लिए, "..."विस्तार के चारों ओर उपयोग करें *_"$testseq"_*:। यह एक स्ट्रिंग के रूप में चर के मूल्य का उपयोग करेगा। क्या आप एक पैटर्न के रूप में चर के मूल्य का उपयोग करना चाहते हैं , *_${testseq}_*इसके बजाय का उपयोग करें ।

एक और त्वरित फिक्स में $testseqनिम्न को शामिल करना है :

testseq="_gen_"

और फिर *"$testseq"*पैटर्न (स्ट्रिंग तुलना के लिए) के रूप में उपयोग करें ।


तो शेल एक चर $ testseq_ की तलाश में होगा और इसे नहीं ढूंढेगा और इसे खाली स्ट्रिंग के साथ स्थानापन्न करेगा।
Viesturs

@Viesturs इस मुद्दे का दिल है, हाँ।
Kusalananda

1
सबस्ट्रिंग के लिए खोज यह होना चाहिए *"$testseq"*के लिए caseकी तरह के लिए [[...]](सिवाय zsh के लिए जब तक आप सक्षम globsubst)
स्टीफन Chazelas
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.