কোনও স্ট্রিংয়ে POSIX sh এ অন্য স্ট্রিং রয়েছে কিনা আপনি কীভাবে বলবেন?


136

আমি একটি ইউনিক্স শেল স্ক্রিপ্ট লিখতে চাই যা অন্য স্ট্রিংয়ের অভ্যন্তরে একটি স্ট্রিং থাকলে বিভিন্ন যুক্তি তৈরি করে। উদাহরণস্বরূপ, আমি যদি একটি নির্দিষ্ট ফোল্ডারে থাকি তবে শাখা বন্ধ করে দিন। কেউ আমাকে কীভাবে এটি সম্পাদন করতে পারেন দয়া করে বলতে পারেন? সম্ভব হলে আমি এটিকে শেল নির্দিষ্ট নয় (যেমন কেবল বাশ নয়) করতে চাই তবে অন্য কোনও উপায় না থাকলে আমি এটিকে করতে পারি।

#!/usr/bin/env sh

if [ "$PWD" contains "String1" ]
then
    echo "String1 present"
elif [ "$PWD" contains "String2" ]
then
    echo "String2 present"
else
    echo "Else"
fi

2
আমি বুঝতে পেরেছি এটি পুরানো, তবে ভবিষ্যতের দর্শকদের জন্য এখানে কয়েকটি বিষয় লক্ষণীয়: (1) পরিবেশ এবং শেল অভ্যন্তরীণ ভেরিয়েবলের জন্য SNAKE_CASE ভেরিয়েবলের নাম সংরক্ষণ করা সাধারণত ভাল অনুশীলন। (2) সেটিং CURRENT_DIRঅতিরিক্ত কাজ; আপনি শুধু ব্যবহার করতে পারেন $PWD
nyuszika7h

উত্তর:


162

এখানে আরও একটি সমাধান এখানে। এটি পসিক্স স্ট্রিং প্যারামিটার সম্প্রসারণ ব্যবহার করে , সুতরাং এটি ব্যাশ, ড্যাশ, কর্নশেল (কেএসএস), জেড শেল (জেডএস), ইত্যাদিতে কাজ করে

test "${string#*$word}" != "$string" && echo "$word found in $string"

কয়েকটি উদাহরণ সহ একটি কার্যকরী সংস্করণ:

# contains(string, substring)
#
# Returns 0 if the specified string contains the specified substring,
# otherwise returns 1.
contains() {
    string="$1"
    substring="$2"
    if test "${string#*$substring}" != "$string"
    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"

3
যদি স্ট্রিংগুলিতে ব্যাকস্ল্যাশ থাকে তবে এটি আমার পক্ষে কাজ করে না। যথারীতি substring="$( printf '%q' "$2" )"দিনটি বাঁচায়।
ডিম টেনসিন

এটি ভুল সাবস্ট্রিন্সগের সাথেও মেলে। স্ট্রিং = "অ্যাপ্লা বিটা বিটাওন" সাবস্ট্রিং = "বিটা"। এটি বিটাওন একটি ডিবেটা উভয়ের সাথেই মেলে, যদিও আমি মনে করি এটি ভুল।
রাজীব

1
ওয়াইল্ডকার্ড ব্যবহার সম্পর্কে কী ? [[ $haystack == *"My needle"* ]]
পাবলো এ

3
ভুলটি হ'ল ডাবল-বন্ধনীগুলি পসিক্স নয়, এটি ছিল প্রশ্নটির মূল ভিত্তি, @ পাবলো।
রব কেনেডি

1
এটি বিশেষ চরিত্রের মতো কাজ করে না []। আমার উত্তর দেখুন stackoverflow.com/a/54490453/712666
অ্যালেক্স স্ক্রিপনিক

85

খাঁটি পসিক্স শেল:

#!/bin/sh
CURRENT_DIR=`pwd`

case "$CURRENT_DIR" in
  *String1*) echo "String1 present" ;;
  *String2*) echo "String2 present" ;;
  *)         echo "else" ;;
esac

Ksh বা বাশের মতো বর্ধিত শেলগুলিতে অভিনব মিল রয়েছে, তবে পুরানো শৈলী caseআশ্চর্যরকম শক্তিশালী।


40

দুঃখের বিষয়, sh এ করার কোনও উপায় সম্পর্কে আমি অবগত নই। তবে, ব্যাশ ব্যবহার করে (3.0.০.০ সংস্করণে শুরু হওয়া যা সম্ভবত আপনার কাছে রয়েছে) আপনি = like অপারেটরটি এর মতো ব্যবহার করতে পারেন:

#!/bin/bash
CURRENT_DIR=`pwd`

if [[ "$CURRENT_DIR" =~ "String1" ]]
then
 echo "String1 present"
elif [[ "$CURRENT_DIR" =~ "String2" ]]
then
 echo "String2 present"
else
 echo "Else"
fi

একটি যুক্ত বোনাস হিসাবে (এবং / অথবা একটি সতর্কতা, যদি আপনার স্ট্রিংগুলিতে কোনও মজার চরিত্র থাকে), = you আপনি উদ্ধৃতিগুলি বাদ দিলে ডান ক্রিয়াকলাপ হিসাবে রেজিক্সগুলি গ্রহণ করে।


3
রেজেক্সকে উদ্ধৃত করবেন না, বা এটি সাধারণভাবে কাজ করবে না । উদাহরণস্বরূপ, [[ test =~ "test.*" ]]বনাম চেষ্টা করুন [[ test =~ test.* ]]
l0b0

1
ঠিক আছে, আপনি যদি আসল প্রশ্নের মতো কোনও স্ট্রিংয়ের জন্য পরীক্ষা করছেন তবে এটি ঠিক কাজ করবে তবে এটি সঠিক ক্রিয়াকে রেজেক্স হিসাবে বিবেচনা করবে না। আমি আরও উত্তর পরিষ্কার করতে আমার উত্তর আপডেট করব।
জন হিল্যান্ড

3
এটি প্রশ্ন, প্রশ্ন হিসাবে পোসিক্স শ নয়, বাশ।
রিড

28
#!/usr/bin/env sh

# Searches a subset string in a string:
# 1st arg:reference string
# 2nd arg:subset string to be matched

if echo "$1" | grep -q "$2"
then
    echo "$2 is in $1"
else 
    echo "$2 is not in $1"
fi

2
অনাকাঙ্ক্ষিত আউটপুট এড়ানোর grep -q "$2"জন্য পরিবর্তন করুন grep -q "$2" > /dev/null
ভিক্টর সার্জিইঙ্কো

15

এখানে একটি লিঙ্ক দেওয়া আছেআপনার সমস্যার বিভিন্ন সমাধানের ।

এটি আমার সবচেয়ে প্রিয় কারণ এটি সর্বাধিক মানব পাঠযোগ্য বোধ করে:

দ্য স্টার ওয়াইল্ডকার্ড পদ্ধতি

if [[ "$string" == *"$substring"* ]]; then
    return 1
fi
return 0

উপর shআমি এই সাথে "অজানা প্রতীক" লাভ করেন। যদিও বাশের সাথে কাজ করে।
অর্ধেক

13
[[পসিক্স নয়
আয়ান

14
case $(pwd) in
  *path) echo "ends with path";;
  path*) echo "starts with path";;
  *path*) echo "contains path";;
  *) echo "this is the default";;
esac


2
test $(echo "stringcontain" "ingcon" |awk '{ print index($1, $2) }') -gt 0 && echo "String 1 contain string 2"

-> আউটপুট: স্ট্রিং 1 এ স্ট্রিং 2 থাকে


2

'পরীক্ষা' প্রোগ্রামটির ম্যানপেজটি দেখুন। আপনি যদি কেবল কোনও ডিরেক্টরি অস্তিত্বের জন্য পরীক্ষা করে থাকেন তবে আপনি সাধারণত এমন কিছু করতে পারেন:

if test -d "String1"; then
  echo "String1 present"
end

যদি আপনি আসলে কোনও স্ট্রিংয়ের সাথে মেলে চেষ্টা করছেন তবে আপনি ব্যাশ সম্প্রসারণের নিয়ম এবং ওয়াইল্ডকার্ডও ব্যবহার করতে পারেন:

if test -d "String*"; then
  echo "A directory starting with 'String' is present"
end

আপনার যদি আরও জটিল কিছু করার দরকার হয় তবে আপনাকে এক্সপ্রেসের মতো অন্য একটি প্রোগ্রাম ব্যবহার করতে হবে।


1
আপনার দ্বিতীয় উদাহরণে একটি উত্সাহী ডাবল উদ্ধৃতি (") বলে মনে হচ্ছে
অ্যালেক্সিস উইলক

2

বিশেষ ক্ষেত্রে যেখানে আপনি একটি শব্দ দীর্ঘ পাঠ্যের মধ্যে রয়েছে কিনা তা জানতে চান, আপনি লুপের সাহায্যে দীর্ঘ পাঠ্যের মাধ্যমে পুনরাবৃত্তি করতে পারেন।

found=F
query_word=this
long_string="many many words in this text"
for w in $long_string; do
    if [ "$w" = "$query_word" ]; then
          found=T
          break
    fi
done

এটি খাঁটি বোর্ন শেল।


1

আপনি যদি কোনও পরীক্ষার মতো দ্রুততর একটি কেএসএস পদ্ধতি চান তবে আপনি এর মতো কিছু করতে পারেন:

contains() # haystack needle
{
    haystack=${1/$2/}
    if [ ${#haystack} -ne ${#1} ] ; then
        return 1
    fi
    return 0
}

এটি খড়ের খড়ের সুইটিকে মুছে ফেলার মাধ্যমে এবং তারপরে পুরানো এবং নতুন খড়ের কাঠের দৈর্ঘ্যের তুলনা করে কাজ করে।


1
এর ফলাফলটি ফেরানো কি সম্ভব হবে না test? যেমন আছে return [ ${#haystack} -eq ${#1} ]?
অ্যালেক্সিস উইলক

হ্যা ঐটা সঠিক. সাধারণ লোকের পক্ষে এটি বোঝা সহজ হিসাবে আমি এটি ছেড়ে দেব। আপনি যদি আপনার কোড ব্যবহার করেন তবে @ অ্যালেক্সিসওয়িল্ক পদ্ধতিটি ব্যবহার করুন।
জোঅফটেক্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.