স্ট্রিংয়ের একটি স্ট্রিং থাকে কিনা তা পরীক্ষা করুন


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একটি নিদর্শন হিসাবে বিবেচিত)।

অথবা _ভেরিয়েবলের নামের সাথে সাথে ভেরিয়েবলের নামের অংশ হিসাবে নেওয়া হবে (এটি একটি ভেরিয়েবল নামের একটি বৈধ অক্ষর)।


ওপির ক্ষেত্রে প্রযোজ্য ঠিক উত্তর, তবে ডাব্লু / ও বহনযোগ্য। (এটি প্রদত্ত উত্তরের কোনও সমালোচনা নয়, পাঠকদের জন্য কেবল একটি সতর্কতা)। ;-)
সিবিহে

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]উদাহরণস্বরূপ) "ম্যাচ" ট্রিগার করার আরও বেশি সুযোগ রয়েছে chance

তথ্যসূত্র :


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

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

case ... esacপোর্টেবল উপায়ে প্যাটার্ন ম্যাচটি সম্পাদন করার অন্যতম সহজ উপায় ব্যবহার Using এটি অন্যান্য ভাষায় একটি "সুইচ" বিবৃতি হিসাবে কাজ করে ( bash, zsh, এবং ksh93এছাড়াও আপনাকে যা করতে পারবেন পতনের মাধ্যমে বিভিন্ন বেমানান উপায়ে)। ব্যবহৃত নিদর্শনগুলি হ'ল স্ট্যান্ডার্ড ফাইলের নাম গ্লোব্বিং নিদর্শন।

আপনার যে সমস্যাটি হচ্ছে তা হ'ল এটি _একটি ভেরিয়েবল নামের বৈধ চরিত্রের কারণে । শেলটি এইভাবে *_$testseq_*" *_ভেরিয়েবল $testseq_এবং একটি এর মান অনুসারে " হিসাবে দেখবে *। ভেরিয়েবল $testseq_অপরিজ্ঞাত, তাই এটি একটি ফাঁকা স্ট্রিংয়ে প্রসারিত হবে এবং আপনি শেষ করবেন *_*যা স্পষ্টতই আপনার সাথে থাকা $fileমানটির সাথে মেলে । Trueফাইলের নামটিতে যতক্ষণ না $fileঅন্তত একটি আন্ডারস্কোর থাকে ততক্ষণ আপনি প্রত্যাশা করতে পারেন ।

সঠিকভাবে পরিবর্তনশীল, ব্যবহারের নাম সীমানা করার "..."সম্প্রসারণ প্রায়: *_"$testseq"_*। এটি স্ট্রিং হিসাবে ভেরিয়েবলের মান ব্যবহার করবে। আপনি কি ভেরিয়েবলের মানটি একটি প্যাটার্ন হিসাবে ব্যবহার করতে চান , *_${testseq}_*পরিবর্তে ব্যবহার করুন।

আর একটি দ্রুত ফিক্স হ'ল আন্ডারস্কোরগুলি এর মানতে অন্তর্ভুক্ত করা $testseq:

testseq="_gen_"

এবং তারপরে কেবল *"$testseq"*প্যাটার্ন হিসাবে ব্যবহার করুন (স্ট্রিং তুলনার জন্য)।


সুতরাং শেলটি একটি ভেরিয়েবল $ testseq_ সন্ধান করবে এবং এটি খুঁজে পাবে না এবং এটি একটি খালি স্ট্রিংয়ের সাথে প্রতিস্থাপন করবে।
ভিয়েস্টার্স

@ ভাইস্টার্স হ'ল ইস্যুটির হৃদয়।
কুসালানন্দ

1
একটি সাবস্ট্রিং জন্য অনুসন্ধান করুন এটি হওয়া উচিত *"$testseq"*জন্য caseমত [[...]](-setup zsh জন্য যদি না আপনি সক্ষম globsubst)
Stéphane Chazelas
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.