বাশ অ্যারেতে কোনও মান রয়েছে কিনা তা পরীক্ষা করুন


443

বাশ-এ, অ্যারেটিতে একটি নির্দিষ্ট মান রয়েছে কিনা তা পরীক্ষা করার সহজ উপায় কী?

সম্পাদনা করুন : কিছু পরীক্ষার পরে উত্তর এবং মন্তব্যগুলির সাহায্যে আমি এটি নিয়ে এসেছি:

function contains() {
    local n=$#
    local value=${!n}
    for ((i=1;i < $#;i++)) {
        if [ "${!i}" == "${value}" ]; then
            echo "y"
            return 0
        fi
    }
    echo "n"
    return 1
}

A=("one" "two" "three four")
if [ $(contains "${A[@]}" "one") == "y" ]; then
    echo "contains one"
fi
if [ $(contains "${A[@]}" "three") == "y" ]; then
    echo "contains three"
fi

আমি এটি সেরা সমাধান কিনা তা নিশ্চিত নই, তবে এটি কার্যকর বলে মনে হচ্ছে।

উত্তর:


457

এই পদ্ধতির সমস্ত উপাদানকে লুপ না করার সুবিধা রয়েছে (কমপক্ষে স্পষ্টভাবে নয়)। কিন্তু যেহেতু array_to_string_internal()array.c এখনও একটি স্ট্রিং মধ্যে অ্যারে উপাদান এবং তাদের যোগসূত্র ধরে loops, এটি সম্ভবত না আরো দক্ষ চেয়ে লুপিং সমাধান প্রস্তাবিত, কিন্তু এটি আরো পাঠযোগ্য নয়।

if [[ " ${array[@]} " =~ " ${value} " ]]; then
    # whatever you want to do when array contains value
fi

if [[ ! " ${array[@]} " =~ " ${value} " ]]; then
    # whatever you want to do when array doesn't contain value
fi

মনে রাখবেন যে ক্ষেত্রে আপনি যে মানটির সন্ধান করছেন সেগুলি শূন্যস্থানগুলির সাথে একটি অ্যারের উপাদানগুলির মধ্যে একটি শব্দ, এটি মিথ্যা ধনাত্মকতা দেবে। উদাহরণ স্বরূপ

array=("Jack Brown")
value="Jack"

রেজেক্স "জ্যাক "টিকে অ্যারেতে থাকা হিসাবে দেখবে যদিও তা না হলেও। সুতরাং আপনি IFSযদি এই সমাধানটি এখনও ব্যবহার করতে চান তবে আপনার রেজেজেসে পৃথককারী চরিত্রগুলি পরিবর্তন করতে হবে

IFS=$'\t'
array=("Jack Brown\tJack Smith")
unset IFS
value="Jack"

if [[ "\t${array[@]}\t" =~ "\t${value}\t" ]]; then
    echo "true"
else
    echo "false"
fi

এটি "মিথ্যা" মুদ্রণ করবে।

অবশ্যই এটি টেস্ট স্টেটমেন্ট হিসাবে ব্যবহার করা যেতে পারে, এটি ওয়ান-লাইনার হিসাবে প্রকাশ করার অনুমতি দেয়

[[ " ${array[@]} " =~ " ${value} " ]] && echo "true" || echo "false"

1
আমি প্রথম রেইগেক্স মান মিলের শুরুতে একটি স্থান যুক্ত করেছি, যাতে এটি কেবল শব্দের সাথে মিলবে, শব্দের সাথে শেষ হওয়া কিছু নয়। দুর্দান্ত কাজ করে। যাইহোক, কেন আপনি দ্বিতীয় শর্তটি ব্যবহার করেন তা আমি বুঝতে পারছি না, প্রথম কাজটি একা ভাল হবে না?
JStrahl

1
@ আউকিউরুইগুও আমি নিশ্চিত নই আমি অনুসরণ করছি আপনি ডলার আক্ষরিক সাথে অ্যারে সম্পর্কে কথা বলছেন? যদি তা হয় তবে ব্যাকস্ল্যাশগুলির সাথে আপনি যে মানটির সাথে মিল করছেন তার মধ্যে ডলারের হাত থেকে বাঁচার বিষয়টি নিশ্চিত করুন।
কেগান

10
অনেলাইনার:[[ " ${branches[@]} " =~ " ${value} " ]] && echo "YES" || echo "NO";
এরিকসন.সেপদা

3
শেলচেক এসসি 2199 এবং এসসি 2076 এই সমাধান সম্পর্কে অভিযোগ করে। কার্যকারিতা ভঙ্গ না করে আমি সতর্কতাগুলি ঠিক করতে পারি না। এই লাইনের জন্য শেলচেক অক্ষম করা ছাড়া অন্য যে কোনও চিন্তা?
আলী Essam

4
SC2076 ঠিক করা সহজ, কেবলমাত্র ডাবল উদ্ধৃতিগুলি সরিয়ে দিন if। আমি মনে করি না এই পদ্ধতির সাথে এসসি 2199 এড়ানোর কোনও উপায় আছে । অন্যান্য কয়েকটি সমাধানে যেমন দেখানো হয়েছে তেমন অ্যারে হলেও আপনাকে স্পষ্টতই লুপ করতে হবে, বা সতর্কতাটিকে উপেক্ষা করতে হবে।
কেগান

388

এটি অর্জনের জন্য নীচে একটি ছোট ফাংশন রয়েছে। অনুসন্ধানের স্ট্রিংটি প্রথম যুক্তি এবং বাকিগুলি অ্যারে উপাদানগুলি:

containsElement () {
  local e match="$1"
  shift
  for e; do [[ "$e" == "$match" ]] && return 0; done
  return 1
}

এই ফাংশনটির একটি পরীক্ষা চালানোর মতো হতে পারে:

$ array=("something to search for" "a string" "test2000")
$ containsElement "a string" "${array[@]}"
$ echo $?
0
$ containsElement "blaha" "${array[@]}"
$ echo $?
1

5
সুন্দরভাবে কাজ করে! আমি শুধু কোট দিয়ে যেমন অ্যারে পাস মনে রাখতে হবে: "${array[@]}"। অন্যথায় স্পেসযুক্ত উপাদানগুলি কার্যকারিতা ভঙ্গ করবে।
জুভ

26
খুশী হলাম। আমি এটিকে উপাদান হিসাবে ডাকি () কারণ এটি প্রথম তর্কটি দ্বিতীয়টিতে অন্তর্ভুক্ত রয়েছে কিনা তা যাচাই করে। এলিমেটমেন্টস () এর মতো অ্যারে আগে চলে আসে like আমার মতো নবাগতদের জন্য, "যদি" বিবৃতিতে স্টাডাউটকে লিখতে না পারে এমন কোনও ফাংশন কীভাবে ব্যবহার করা যায় তার একটি উদাহরণ: if elementIn "$table" "${skip_tables[@]}" ; then echo skipping table: ${table}; fi; আপনার সহায়তার জন্য ধন্যবাদ!
গ্লেনপিটারসন

5
@ ব্লুজ অ্যান্ড অ্যান্ড কনস্ট্রাক্ট হ'ল বুলিয়ান অ্যান্ড অপারেটর। বুলিয়ান অপারেটরগুলির ব্যবহার একটি বুলিয়ান বিবৃতি তৈরি করে। বুলিয়ান যুক্তি অনুসারে পুরো বক্তব্যটি কেবল তখনই সত্য হতে পারে যদি &&& এর আগে এবং পরে উভয় বক্তব্য সত্যের কাছে মূল্যায়ন করে। এটি ইনস্টেট করা শর্টকাট হিসাবে এবং যদি ব্লক হিসাবে ব্যবহৃত হয় test পরীক্ষাটি মূল্যায়ন করা হয় এবং মিথ্যা হলে, পরীক্ষার ব্যর্থ হয়ে যায় এবং তাই এটি চালানো হয় না বলে রিটার্নটি পুরো বিবৃতিটির সাথে অপ্রাসঙ্গিক হয় ate যদি পরীক্ষাটি সফল হয় তবে বুলিয়ান বিবৃতিটির সাফল্যের জন্য কোডটি চালিত হওয়ার জন্য ফেরতের ফলাফল নির্ধারণ করা দরকার।
পীটচ

4
@ জেমস কনভেনশন অনুসারে ব্যাশের সাফল্য কোডটি "0" এবং ত্রুটি সবকিছুর> = 1. এই কারণেই এটি সাফল্যে 0 প্রদান করে। :)
tftd

11
@Stelios shiftবদল আনতে বাম (প্রথম যুক্তি ড্রপ) এর 1 যুক্তি তালিকা এবং forছাড়া একটি inপরোক্ষভাবে আর্গুমেন্ট তালিকার উপর iterates।
খ্রিস্টান

58
$ myarray=(one two three)
$ case "${myarray[@]}" in  *"two"*) echo "found" ;; esac
found

69
দ্রষ্টব্য যে এটি অ্যারের প্রতিটি উপাদান পৃথকভাবে পুনরাবৃত্তি করে না ... পরিবর্তে এটি কেবল অ্যারের সাথে সংমিশ্রণ করে এবং "দুটি" একটি স্ট্রিং হিসাবে মেলে। যদি কেউ পরীক্ষা করে দেখায় যে সঠিক শব্দ "দুটি" অ্যারেতে একটি উপাদান কিনা।
মার্টেম্যাকজিভার

আমি ভেবেছিলাম এটি ফাইলের ধরণের তুলনায় আমার পক্ষে কাজ করবে তবে দেখা গেছে যে কাউন্টারগুলি বাড়ার সাথে সাথে এটি অনেকগুলি মান গণনা করছে ... বু!
মাইক কিউ

17
ভুল! কারণ: ফলাফল case "${myarray[@]}" in *"t"*) echo "found" ;; esac:found
সের্গেজ জেভসেজেভ

@MartyMacGyver, আপনি দয়া করে এই উত্তর আমার উপরন্তু উপর চেহারা আছে পারে stackoverflow.com/a/52414872/1619950
আলেক্সান্দ্র Podkutin

45
for i in "${array[@]}"
do
    if [ "$i" -eq "$yourValue" ] ; then
        echo "Found"
    fi
done

স্ট্রিংগুলির জন্য:

for i in "${array[@]}"
do
    if [ "$i" == "$yourValue" ] ; then
        echo "Found"
    fi
done

এটি বলেছিল, আপনি লুপের জন্য একটি সূচক ব্যবহার করতে পারেন এবং অ্যারে উপাদানটিতে আইএফএস থাকা অবস্থায় মারা যাওয়া এড়াতে পারেন: ((i = 0; i <$ {# অ্যারে [@] i; i++)) জন্য
এমকেবি

@ ম্যাট: ${#}বাশ স্পারস অ্যারে সমর্থন করার কারণে আপনাকে সতর্কতা অবলম্বন করতে হবে ।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

@ পাওলো, যদি আপনার অ্যারেতে কোনও স্থান থাকে তবে কেবল স্ট্রিং হিসাবে এটি তুলনা করুন। একটি স্থান পাশাপাশি একটি স্ট্রিং হয়।
স্কট

@ পাওলো: আপনি এটি একটি ফাংশন করতে পারেন, তবে অ্যারেগুলি আর্গুমেন্ট হিসাবে পাস করা যায় না তাই আপনাকে এটিকে বিশ্বব্যাপী হিসাবে বিবেচনা করতে হবে।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

ডেনিস ঠিক আছে। বাশ রেফারেন্স ম্যানুয়াল থেকে: "যদি শব্দটি ডাবল-কোট করা হয়, ... $ {নাম [@] name নামের প্রতিটি উপাদানকে পৃথক শব্দে প্রসারিত করে"
এম কে বি

37

এক-লাইন সমাধান

printf '%s\n' ${myarray[@]} | grep -P '^mypattern$'

ব্যাখ্যা

printfবিবৃতি আলাদা লাইনে অ্যারের প্রতিটি উপাদান ছাপে।

grepবিবৃতি বিশেষ অক্ষর ব্যবহার ^এবং $একটি লাইন রয়েছে সেটা খুঁজে পেতে ঠিক প্যাটার্ন হিসেবে দেওয়া mypattern(আর কোনো কোনো কম)।


ব্যবহার

এটি একটি if ... thenবিবৃতিতে রাখা:

if printf '%s\n' ${myarray[@]} | grep -q -P '^mypattern$'; then
    # ...
fi

আমি এক্সপ্রেশনটিতে একটি -qপতাকা যুক্ত করেছি grepযাতে এটি মিলগুলি মুদ্রণ করে না; এটি কেবল ম্যাচের অস্তিত্বকে "সত্য" হিসাবে বিবেচনা করবে।


চমৎকার সমাধান! জিএনইউ গ্রেপ-এ, "--line-regexp" রয়েছে যা "-P" এবং pattern এবং the প্যাটার্নে প্রতিস্থাপন করতে পারে: প্রিন্টফ '% s \ n' $ {মায়ার্য [@]} | গ্রেপ-কি - লাইন-রেজিপ্সপ 'মাইপ্যাটার্ন'
প্রিস্টো 8

19

আপনার যদি পারফরম্যান্সের প্রয়োজন হয় তবে আপনি অনুসন্ধানের সময় আপনার পুরো অ্যারেটি লুপ করতে চান না।

এই ক্ষেত্রে, আপনি একটি সহযোগী অ্যারে (হ্যাশ টেবিল, বা অভিধান) তৈরি করতে পারেন যা সেই অ্যারের সূচকটি উপস্থাপন করে। অর্থাৎ এটি অ্যারেতে প্রতিটি অ্যারে উপাদানটিকে তার সূচীতে মানচিত্র করে:

make_index () {
  local index_name=$1
  shift
  local -a value_array=("$@")
  local i
  # -A means associative array, -g means create a global variable:
  declare -g -A ${index_name}
  for i in "${!value_array[@]}"; do
    eval ${index_name}["${value_array[$i]}"]=$i
  done
}

তারপরে আপনি এটি ব্যবহার করতে পারেন:

myarray=('a a' 'b b' 'c c')
make_index myarray_index "${myarray[@]}"

এবং পরীক্ষার সদস্যতা যেমন:

member="b b"
# the "|| echo NOT FOUND" below is needed if you're using "set -e"
test "${myarray_index[$member]}" && echo FOUND || echo NOT FOUND

বা এছাড়াও:

if [ "${myarray_index[$member]}" ]; then 
  echo FOUND
fi

লক্ষ্য করুন যে পরীক্ষিত মান বা অ্যারের মানগুলিতে শূন্যস্থান থাকলেও এই সমাধানটি সঠিক কাজটি করে does

বোনাস হিসাবে, আপনি অ্যারের মধ্যে মানের সূচকটিও পাবেন:

echo "<< ${myarray_index[$member]} >> is the index of $member"

আপনার পরামর্শমূলক অ্যারে ব্যবহার করা উচিত এমন ধারণার জন্য +1। আমি মনে করি এর make_indexদিকনির্দেশনার কারণে কোডটি কিছুটা আরও স্বীকৃত; আপনি অনেক সহজ কোড সহ একটি নির্দিষ্ট অ্যারে নাম ব্যবহার করতে পারতেন।
মুসিফিল

17

আমি সাধারণত:

inarray=$(echo ${haystack[@]} | grep -o "needle" | wc -w)

শূন্য-বিনা মানটি একটি মিল খুঁজে পাওয়া যায়।


সত্য, এটি অবশ্যই সহজতম সমাধান - আমার মতে উত্তর চিহ্নিত করা উচিত। কমপক্ষে আমার উপভোগ করুন! [:
টোভাইন

2
এটি একই সূঁচের জন্য কাজ করবে না। উদাহরণস্বরূপ,haystack=(needle1 needle2); echo ${haystack[@]} | grep -o "needle" | wc -w
কেইগান

1
খুবই সত্য. কোনও এলিমিটারের সাথে যোগ হওয়া যে কোনও উপাদান উপস্থিত নেই এবং এটিতে সুইতে যুক্ত করা এতে সহায়তা করবে। হতে পারে এর মতো কিছু ... ( inarray=$(printf ",%s" "${haystack[@]}") | grep -o ",needle" | wc -w)
স্বাক্ষরিত

2
inarray=$(printf ",%s" "${haystack[@]}") | grep -x "needle" | wc -l
গ্রেপ

সম্ভবত inarray=$(echo " ${haystack[@]}" | grep -o " needle" | wc -w)-x-এর ফলে পুরো ইনপুট স্ট্রিংটির চেষ্টা করে এবং ম্যাচটি তৈরি করার কারণ
এমআই রাইট

17

একটি ফাংশন ছাড়াই অন্য একটি লাইনার:

(for e in "${array[@]}"; do [[ "$e" == "searched_item" ]] && exit 0; done) && echo "found" || echo "not found"

স্থানগুলি সম্পর্কে মাথা উঁচু করার জন্য @ কিওয়ার্টি ধন্যবাদ!

সংশ্লিষ্ট ফাংশন:

find_in_array() {
  local word=$1
  shift
  for e in "$@"; do [[ "$e" == "$word" ]] && return 0; done
  return 1
}

উদাহরণ:

some_words=( these are some words )
find_in_array word "${some_words[@]}" || echo "expected missing! since words != word"

1
আমাদের এখানে কেন সাবসেলের দরকার?
কোডফোরস্টার

1
@ কোডফোরস্টার এটি পুরানো ... তবে এটি যেমন লেখা হয়েছিল আপনার এটিকে ভেঙে ফেলার জন্য এটি প্রয়োজন, এটিই exit 0করেন (যদি পাওয়া যায় তবে ততক্ষণ বন্ধ হয়ে যায়)।
এস্তানি

এক লাইনের শেষের || echo not foundপরিবর্তে হওয়া উচিত || not foundবা শেলটি অনুরোধকৃত মানটি অ্যারেতে না থাকলে খুঁজে পাওয়া যুক্তির সাথে নাম না দিয়ে একটি কমান্ড চালানোর চেষ্টা করবে ।
জোক করুন

11
containsElement () { for e in "${@:2}"; do [[ "$e" = "$1" ]] && return 0; done; return 1; }

এখন খালি অ্যারেগুলি সঠিকভাবে পরিচালনা করে।


@ দেশপ্রেমিকের উত্তরের চেয়ে এটি কীভাবে আলাদা? আমি দেখতে পাচ্ছি একমাত্র পার্থক্য "$e" = "$1"(পরিবর্তে "$e" == "$1") যা বাগের মতো দেখাচ্ছে।
সিভিফ্যান

1
এইটা না. @ দেশপ্রেমিক আমার মন্তব্যটি তার মূল উত্তরে ফিরে এসেছিল (প্যাচ # 4)। দ্রষ্টব্য: "e" == "$1"বাক্যবৈজ্ঞানিকভাবে পরিষ্কার।
ইয়ান

@ সিভিফ্যান তার বর্তমান আকারে মার্জিত $ {@: 2} এবং স্ব ডকুমেন্টিং $ 1 এর কারণে এটি দেশপ্রেমিকের জবাবের চেয়ে ছোট। আমি যুক্ত করব যে [[]] এর মধ্যে উদ্ধৃতি আবশ্যক নয়।
হন্টভেরি লেভেন্তে

9

এখানে একটি ছোট অবদান:

array=(word "two words" words)  
search_string="two"  
match=$(echo "${array[@]:0}" | grep -o $search_string)  
[[ ! -z $match ]] && echo "found !"  

দ্রষ্টব্য: এইভাবে কেস "দুটি শব্দ" কে আলাদা করে না তবে প্রশ্নটিতে এটি প্রয়োজন হয় না।


এই আমাকে অনেক সাহায্য করেছে। ধন্যবাদ!
এড মানেট

প্রশ্নটি স্পষ্টভাবে বলেন নি যে আপনাকে সঠিক উত্তর দিতে হবে তবে আমি মনে করি এটি প্রশ্নের মধ্যে অন্তর্ভুক্ত ... অ্যারেতে "দুটি" মান নেই।
tetsujin

উপরেরগুলি 'আরডি' এর জন্য একটি মিলের প্রতিবেদন করবে।
নোল ইয়াপ

6

আপনি যদি একটি সুনির্দিষ্ট ম্যাচ পেতে পুরো অ্যারেটি ঘুরিয়ে ফেলার মতো তাড়াতাড়ি এবং নোংরা পরীক্ষা করতে চান, বাশ স্ক্রারের মতো অ্যারেগুলিকে চিকিত্সা করতে পারে। স্কেলারে কোনও ম্যাচের জন্য পরীক্ষা করুন, যদি না হয় তবে লুপটি এড়িয়ে যাওয়া সময় সাশ্রয় করে। অবশ্যই আপনি মিথ্যা ইতিবাচক পেতে পারেন।

array=(word "two words" words)
if [[ ${array[@]} =~ words ]]
then
    echo "Checking"
    for element in "${array[@]}"
    do
        if [[ $element == "words" ]]
        then
            echo "Match"
        fi
    done
fi

এটি "চেকিং" এবং "ম্যাচ" আউটপুট দেবে। array=(word "two words" something)এটির সাথে কেবল "চেকিং" আউটপুট হবে। সাথে array=(word "two widgets" something)কোনও আউটপুট হবে না।


কেবলমাত্র পুরো wordsরেখার সাথে ^words$মেলে এমন একটি রেজেক্সের সাথে কেন প্রতিস্থাপন করবেন না , যা প্রতিটি আইটেমকে পৃথকভাবে চেক করার প্রয়োজনীয়তা পুরোপুরি বাদ দেয়?
দেজয় ক্লেটন

@ দেজাইক্লেটন: কারণ pattern='^words$'; if [[ ${array[@]} =~ $pattern ]]এটি কখনই মিলবে না কারণ এটি একবারে পুরো অ্যারেটি পরীক্ষা করে দেখে মনে হচ্ছে এটি কোনও স্কেলারের মতো। আমার উত্তরের স্বতন্ত্র চেকগুলি কেবল তখনই করা উচিত যদি মোটামুটি ম্যাচের উপর ভিত্তি করে এগিয়ে যাওয়ার কারণ থাকে।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

আহ, আমি যা করতে চাইছি তা আমি দেখতে পাচ্ছি। আমি একটি বৈকল্পিক উত্তর প্রস্তাব করেছি যা আরও পারফরম্যান্ট এবং সুরক্ষিত।
দেজয় ক্লেটন

6

এটি আমার পক্ষে কাজ করছে:

# traditional system call return values-- used in an `if`, this will be true when returning 0. Very Odd.
contains () {
    # odd syntax here for passing array parameters: http://stackoverflow.com/questions/8082947/how-to-pass-an-array-to-a-bash-function
    local list=$1[@]
    local elem=$2

    # echo "list" ${!list}
    # echo "elem" $elem

    for i in "${!list}"
    do
        # echo "Checking to see if" "$i" "is the same as" "${elem}"
        if [ "$i" == "${elem}" ] ; then
            # echo "$i" "was the same as" "${elem}"
            return 0
        fi
    done

    # echo "Could not find element"
    return 1
}

উদাহরণ কল:

arr=("abc" "xyz" "123")
if contains arr "abcx"; then
    echo "Yes"
else
    echo "No"
fi

5
a=(b c d)

if printf '%s\0' "${a[@]}" | grep -Fqxz c
then
  echo 'array “a” contains value “c”'
fi

আপনি যদি পছন্দ করেন তবে সমপরিমাণ দীর্ঘ বিকল্পগুলি ব্যবহার করতে পারেন:

--fixed-strings --quiet --line-regexp --null-data

1
ম্যাকের বিএসডি-গ্রেপের সাথে এটি কাজ করে না, কারণ কোনও নন-ডেটা নেই। :(
উইল

4

থেকে ধার ডেনিস উইলিয়ামসন এর উত্তর , নিম্নলিখিত সমাধান সম্মিলন অ্যারে, শেল-নিরাপদ উদ্ধৃত, এবং রেগুলার এক্সপ্রেশনের জন্য প্রয়োজন এড়াতে: লুপ উপর iterating; পাইপ বা অন্যান্য উপ-প্রক্রিয়া ব্যবহার করে; বা নন-ব্যাশ ইউটিলিটিগুলি ব্যবহার করে।

declare -a array=('hello, stack' one 'two words' words last)
printf -v array_str -- ',,%q' "${array[@]}"

if [[ "${array_str},," =~ ,,words,, ]]
then
   echo 'Matches'
else
   echo "Doesn't match"
fi

উপরের কোডটি অ্যারে সামগ্রীর স্ট্রিংফাইড সংস্করণটির সাথে মিল রাখতে বাশ নিয়মিত প্রকাশের সাহায্যে কাজ করে। নিয়মিত এক্সপ্রেশন ম্যাচ অ্যারের মধ্যে মানের চতুর সংমিশ্রণ দ্বারা বোকা বানানো যাবে না তা নিশ্চিত করার জন্য ছয়টি গুরুত্বপূর্ণ পদক্ষেপ রয়েছে:

  1. বাশের অন্তর্নির্মিত printfশেল-উদ্ধৃতি ব্যবহার করে তুলনা স্ট্রিংটি তৈরি করুন %q। শেল-উদ্ধৃতি নিশ্চিত করবে যে ব্যাকস্ল্যাশ দিয়ে পালিয়ে গিয়ে বিশেষ অক্ষরগুলি "শেল-সেফ" হয়ে উঠবে \
  2. মান ডিলিমিটার হিসাবে পরিবেশন করতে একটি বিশেষ চরিত্র চয়ন করুন। ডিলিমিটার হ'ল বিশেষ চরিত্রগুলির মধ্যে একটি যা ব্যবহার করার পরে পালাতে সক্ষম হবে %q; নিয়মিত এক্সপ্রেশন ম্যাচটিকে বোকা বানানোর জন্য চূড়ান্ত উপায়ে অ্যারের মধ্যে মানগুলি তৈরি করা যায় না তার গ্যারান্টি দেওয়ার একমাত্র উপায়। আমি কমা বেছে নিই, কারণ অন্যথায় অপ্রত্যাশিত উপায়ে যখন বিকশিত বা অপব্যবহার করা হয় তখন সেই চরিত্রটি সবচেয়ে নিরাপদ।
  3. ডিলিমিটার হিসাবে পরিবেশন করতে বিশেষ চরিত্রের দুটি উদাহরণ ব্যবহার করে সমস্ত অ্যারে উপাদানকে একটি একক স্ট্রিংয়ে একত্রিত করুন। উদাহরণ হিসাবে কমা ব্যবহার করে, আমি ,,%qতর্ক হিসাবে ব্যবহার করেছি printf। এটি গুরুত্বপূর্ণ কারণ বিশেষ চরিত্রের দুটি উদাহরণ কেবল তখন একে অপরের পাশে উপস্থিত হতে পারে যখন তারা সীমানা হিসাবে উপস্থিত হয়; বিশেষ চরিত্রের অন্যান্য সমস্ত দৃষ্টিকোণ পালিয়ে যাবে।
  4. অ্যারের শেষ উপাদানটির সাথে ম্যাচগুলিকে মঞ্জুরি দেওয়ার জন্য স্ট্রিমটিতে ডিলিমিটারের দুটি পেছনের উদাহরণ সংযোজন করুন। সুতরাং, পরিবর্তে বিরুদ্ধে তুলনা ${array_str}বিরুদ্ধে তুলনা ${array_str},,
  5. আপনি যে টার্গেটের স্ট্রিংটি সন্ধান করছেন তা যদি কোনও ব্যবহারকারী ভেরিয়েবল সরবরাহ করে তবে আপনার অবশ্যই বিশেষ অক্ষরের সমস্ত উদাহরণকে ব্যাকস্ল্যাশ সহ এড়াতে হবে। অন্যথায়, নিয়মিত অভিব্যক্তি ম্যাচটি চতুরতার সাথে কারুকৃত অ্যারে উপাদানগুলির দ্বারা বোকা হওয়ার ঝুঁকিতে পরিণত হয়।
  6. স্ট্রিংয়ের বিরুদ্ধে বাশ নিয়মিত অভিব্যক্তি ম্যাচটি সম্পাদন করুন।

খুব চালাক. আমি দেখতে পাচ্ছি যে বেশিরভাগ সম্ভাব্য সমস্যাগুলি প্রতিরোধ করা হয়েছে, তবে কোনও কোণার ঘটনা আছে কিনা তা পরীক্ষা করে দেখতে চাই। এছাড়াও, আমি বিন্দু হ্যান্ডলিং 5. কিছু একটি উদাহরণ দেখতে চাই printf -v pattern ',,%q,,' "$user_input"; if [[ "${array_str},," =~ $pattern ]]সম্ভবত।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

case "$(printf ,,%q "${haystack[@]}"),," in (*"$(printf ,,%q,, "$needle")"*) true;; (*) false;; esac
টিনো

3

caseঅ্যারেতে নির্দিষ্ট মান রয়েছে কিনা তা পরীক্ষা করতে যুক্তি ব্যবহার সম্পর্কে @ ঘোস্টডোগ 74৪ এর উত্তরে একটি ছোট সংযোজন রয়েছে:

myarray=(one two three)
word=two
case "${myarray[@]}" in  ("$word "*|*" $word "*|*" $word") echo "found" ;; esac

অথবা extglobবিকল্পটি চালু করার সাথে আপনি এটি এটি করতে পারেন:

myarray=(one two three)
word=two
shopt -s extglob
case "${myarray[@]}" in ?(*" ")"$word"?(" "*)) echo "found" ;; esac

এছাড়াও আমরা ifবিবৃতি দিয়ে এটি করতে পারি :

myarray=(one two three)
word=two
if [[ $(printf "_[%s]_" "${myarray[@]}") =~ .*_\[$word\]_.* ]]; then echo "found"; fi

2

প্রদত্ত:

array=("something to search for" "a string" "test2000")
elem="a string"

তারপরে একটি সাধারণ চেক:

if c=$'\x1E' && p="${c}${elem} ${c}" && [[ ! "${array[@]/#/${c}} ${c}" =~ $p ]]; then
  echo "$elem exists in array"
fi

কোথায়

c is element separator
p is regex pattern

(সরাসরি ভিতরে ভিতরে এক্সপ্রেশনটি ব্যবহার না করে আলাদাভাবে পি বরাদ্দ করার কারণ [[]] বাশ 4 এর জন্য সামঞ্জস্য বজায় রাখা)


আপনার এখানে "সরল" শব্দটি ব্যবহার পছন্দ করুন ... 😂
খ্রিস্টান

2

এখানে উপস্থাপন করা কয়েকটি ধারণার সংমিশ্রণটি আপনি লুপ ছাড়াই স্ট্যাটেমেট করতে পারেন যা সঠিক শব্দটির সাথে মেলে

$find="myword"
$array=(value1 value2 myword)
if [[ ! -z $(printf '%s\n' "${array[@]}" | grep -w $find) ]]; then
  echo "Array contains myword";
fi

এটি কেবল পুরো শব্দের সাথে মিলবে না wordবা ট্রিগার করবে না val। এটি ভঙ্গ হবে যদি প্রতিটি অ্যারের মানটিতে একাধিক শব্দ থাকে।


1

ভেরিয়েবলের পরিবর্তে ভেরিয়েবলের নামে চালানোর জন্য আমি সাধারণত এই জাতীয় ইউটিলিটিগুলি লিখি, কারণ প্রাথমিকভাবে বাশ অন্যথায় রেফারেন্সের মাধ্যমে ভেরিয়েবলগুলি পাস করতে পারে না।

এখানে একটি সংস্করণ যা অ্যারের নাম নিয়ে কাজ করে:

function array_contains # array value
{
    [[ -n "$1" && -n "$2" ]] || {
        echo "usage: array_contains <array> <value>"
        echo "Returns 0 if array contains value, 1 otherwise"
        return 2
    }

    eval 'local values=("${'$1'[@]}")'

    local element
    for element in "${values[@]}"; do
        [[ "$element" == "$2" ]] && return 0
    done
    return 1
}

এটির সাথে প্রশ্নের উদাহরণটি হয়ে যায়:

array_contains A "one" && echo "contains one"

প্রভৃতি


কেউ যদি এর মধ্যে ব্যবহৃত একটি উদাহরণ পোস্ট করতে পারে, বিশেষত আপনি অ্যারেতে কীভাবে পাস করেন। আমি স্ক্রিপ্টের জন্য একটি যুক্তি পেরেকগুলি অ্যারের হিসাবে বিবেচনা করে পাস করেছি কিনা তা দেখার চেষ্টা করছি, তবে এটি কাজ করতে চায় না। প্যারামস = ("$ @") চেক = অ্যারে_সন্টেন্টস $ {প্যারামস} 'স্কিপডিরচেক' যদি [[$ {চেক করুন} == 1]]; তারপরে .... তবে 'আসস' দিয়ে স্ক্রিপ্টটি যখন আর্গুমেন্ট হিসাবে চালিত হয় তখন এটি আসস বলে চলে: আদেশটি পাওয়া যায় নি। : /
স্টিভ চাইল্ডস

1

ব্যবহার grepএবংprintf

প্রতিটি অ্যারে সদস্যকে একটি নতুন লাইনে ফর্ম্যাট করুন, তারপরে grepলাইনগুলি।

if printf '%s\n' "${array[@]}" | grep -x -q "search string"; then echo true; else echo false; fi
উদাহরণ:
$ array=("word", "two words")
$ if printf '%s\n' "${array[@]}" | grep -x -q "two words"; then echo true; else echo false; fi
true

মনে রাখবেন যে ডিলিমিটার এবং স্পেসগুলির সাথে এটির কোনও সমস্যা নেই।


1

'গ্রেপ' এবং লুপগুলি ছাড়াই এক-লাইনের চেক

if ( dlm=$'\x1F' ; IFS="$dlm" ; [[ "$dlm${array[*]}$dlm" == *"$dlm${item}$dlm"* ]] ) ; then
  echo "array contains '$item'"
else
  echo "array does not contain '$item'"
fi

এই পদ্ধতির বাহ্যিক ইউটিলিটি যেমন grepলুপ বা লুপ ব্যবহার করে না ।

এখানে যা ঘটে তা হ'ল:

  • স্ট্রিতে সংযুক্ত হওয়া অ্যারেতে আমাদের আইটেমটি খুঁজে পেতে আমরা একটি ওয়াইল্ডকার্ড সাবস্ট্রিং ম্যাচার ব্যবহার করি;
  • একজোড়া ডিলিমিটারের মধ্যে আমাদের অনুসন্ধান আইটেমটি আবদ্ধ করে আমরা সম্ভাব্য মিথ্যা ধনাত্মকতা কেটে ফেলেছি;
  • আমরা নিরাপদ দিকে থাকতে ডিলিমিটার হিসাবে একটি মুদ্রণযোগ্য অক্ষর ব্যবহার করি;
  • আমরা IFSভেরিয়েবল মানটির অস্থায়ী প্রতিস্থাপনের মাধ্যমে অ্যারে কনটেনটেশনের জন্যও আমাদের ডিলিমিটার ব্যবহার করি ;
  • আমরা IFSএকটি উপ-শেলের মধ্যে আমাদের শর্তসাপেক্ষ অভিব্যক্তিটি মূল্যায়ন করে এই মান প্রতিস্থাপনকে অস্থায়ী করে তুলি (প্রথম বন্ধকের জুড়ে)

Dlm নির্মূল করুন। সরাসরি আইএফএস ব্যবহার করুন।
রবিন এ। মেড

এটি সেরা উত্তর। আমি এটি খুব পছন্দ করেছিলাম, আমি এই কৌশলটি ব্যবহার করে একটি ফাংশন লিখেছি
রবিন এ মেইড

1

প্যারামিটার সম্প্রসারণ ব্যবহার:

me {প্যারামিটার: + শব্দ} প্যারামিটারটি নাল বা আনসেট না হলে কিছুই প্রতিস্থাপন করা হয়, অন্যথায় শব্দের বিস্তৃতি প্রতিস্থাপিত হয়।

declare -A myarray
myarray[hello]="world"

for i in hello goodbye 123
do
  if [ ${myarray[$i]:+_} ]
  then
    echo ${!myarray[$i]} ${myarray[$i]} 
  else
    printf "there is no %s\n" $i
  fi
done

${myarray[hello]:+_}এসোসিয়েভ অ্যারেগুলির জন্য দুর্দান্ত কাজ করে তবে সাধারণ সূচিযুক্ত অ্যারেগুলির জন্য নয়। প্রশ্নটি অ্যারেতে কোনও মান সন্ধান করার বিষয়ে, কোনও এসোসিয়েটিভ অ্যারের কী উপস্থিত রয়েছে কিনা তা যাচাই করে না।
এরিক

0

উত্তর দেওয়ার পরে, আমি অন্য একটি উত্তর পড়লাম যা আমি বিশেষভাবে পছন্দ করি তবে এটি ত্রুটিযুক্ত এবং হ্রাসযুক্ত ছিল। আমি অনুপ্রেরণা পেয়েছি এবং এখানে দুটি নতুন পন্থা আমি কার্যকর দেখছি।

array=("word" "two words") # let's look for "two words"

ব্যবহার grepএবং printf:

(printf '%s\n' "${array[@]}" | grep -x -q "two words") && <run_your_if_found_command_here>

ব্যবহার for:

(for e in "${array[@]}"; do [[ "$e" == "two words" ]] && exit 0; done; exit 1) && <run_your_if_found_command_here>

Not_found ফলাফল যুক্ত করুন || <run_your_if_notfound_command_here>


0

এই আমার গ্রহণ এখানে।

আমি এড়াতে পারলে লুপের জন্য কোনও ব্যাশ ব্যবহার করব না, কারণ এটি চালাতে সময় লাগে। যদি কোনও জিনিস লুপ করতে হয় তবে এটি এমন কিছু হোক যা শেল স্ক্রিপ্টের চেয়ে নিম্ন স্তরের ভাষায় লেখা হয়েছিল।

function array_contains { # arrayname value
  local -A _arr=()
  local IFS=
  eval _arr=( $(eval printf '[%q]="1"\ ' "\${$1[@]}") )
  return $(( 1 - 0${_arr[$2]} ))
}

এটি একটি অস্থায়ী সহযোগী অ্যারে তৈরি করে কাজ করে _arr, যার সূচকগুলি ইনপুট অ্যারের মান থেকে প্রাপ্ত। (নোট করুন যে সহযোগী অ্যারেগুলি ব্যাশ 4 এবং তত উপরে পাওয়া যায়, সুতরাং এই ফাংশনটি ব্যাশের আগের সংস্করণগুলিতে কাজ করবে না)) আমরা $IFSহোয়াইট স্পেসে শব্দের বিভাজন এড়াতে প্রস্তুত করেছি।

অভ্যন্তরীণভাবে পপুলেশন করার জন্য ইনপুট অ্যারের মাধ্যমে পদক্ষেপগুলি সজ্জিত করা সত্ত্বেও ফাংশনটিতে কোনও স্পষ্ট লুপ থাকে না printf। প্রিন্টফ ফর্ম্যাটটি %qনিশ্চিত করে যাতে ইনপুট ডেটা এড়ানো যায় যাতে তারা নিরাপদে অ্যারে কী হিসাবে ব্যবহার করতে পারে uses

$ a=("one two" three four)
$ array_contains a three && echo BOOYA
BOOYA
$ array_contains a two && echo FAIL
$

নোট করুন যে এই ফাংশনটি ব্যবহার করে তা হ'ল ব্যাশ করার জন্য অন্তর্নির্মিত, সুতরাং কোনও বহিরাগত পাইপ আপনাকে নীচে টেনে নেবে না এমনকি কমান্ড বিস্তারেও।

এবং যদি আপনি ব্যবহার করতে পছন্দ করেন না eval... ভাল, আপনি অন্য পদ্ধতির ব্যবহার করতে পারবেন না। :-)


অ্যারেতে বর্গাকার বন্ধনী থাকলে কী হবে?
gniourf_gniourf

@gniourf_gniourf - বর্গক্ষেত্র বন্ধনী সুষম হলে ঠিক আছে বলে মনে হয় তবে আপনার অ্যারেতে ভারসাম্যহীন বর্গাকার বন্ধনী সহ মানগুলি অন্তর্ভুক্ত করা থাকলে আমি এটি একটি সমস্যা হিসাবে দেখতে পাচ্ছি। সেক্ষেত্রে আমি evalউত্তরটির শেষে নির্দেশটি প্রার্থনা করব । :)
ঘোটি

এটি এমন নয় যে আমি পছন্দ করি না eval(এর বিরুদ্ধে আমার কিছুই নেই, কাঁদতে evalথাকা বেশিরভাগ লোকের মতোই এটি মন্দ, বেশিরভাগই এটি সম্পর্কে কী খারাপ তা বুঝতে না পেরে) evil আপনার আদেশটি ভঙ্গ হয়ে গেছে is হয়তো %qপরিবর্তে %sভাল হবে।
gniourf_gniourf

1
@gniourf_gniourf: আমি কেবল "অন্য পদ্ধতির" বিটটি বোঝাতে চাইছিলাম (এবং আমি পুরোপুরি আপনার সাথে আছি eval, স্পষ্টতই), তবে আপনি একেবারে ঠিক আছেন %q, আমি দেখতে পাচ্ছি এমন কোনও কিছুই না ভেঙে সাহায্য করার জন্য উপস্থিত হয়েছে। (আমি বুঝতে পারিনি যে% কিউ স্কোয়ার বন্ধনীগুলিও এড়ায়। সাথে a=(one "two " three), কেগানের ইস্যুর সাথে সমান: এটি কেবল array_contains a "two "একটি মিথ্যা নেতিবাচকই পায়নি , তবে array_contains a twoএকটি মিথ্যা ধনাত্মকও পেয়েছে। সেট করে ঠিক করার পক্ষে যথেষ্ট সহজ IFS
ঘোটি

হোয়াইটস্পেসগুলি সম্পর্কে, উক্ত উদ্ধৃতিগুলি অনুপস্থিত থাকায় তা নয়? এটি গ্লোব অক্ষরগুলির সাথেও ভেঙে যায়। আমি মনে করি এর পরিবর্তে আপনি এটি চান: eval _arr=( $(eval printf '[%q]="1"\ ' "\"\${$1[@]}\"") )এবং আপনি এটি খনন করতে পারেন local IFS=। অ্যারেতে খালি ক্ষেত্রের সাথে এখনও একটি সমস্যা রয়েছে, কারণ বাশ কোনও সহযোগী অ্যারেতে একটি খালি কী তৈরি করতে অস্বীকার করবে। এটির সমাধানের দ্রুত হ্যাকি উপায় হ'ল একটি ডামি চরিত্রটি প্রিপেন্ড করা, বলুন x: eval _arr=( $(eval printf '[x%q]="1"\ ' "\"\${$1[@]}\"") )এবং return $(( 1 - 0${_arr[x$2]} ))
gniourf_gniourf

-1

আমার নিয়মিত এক্সপ্রেশন কৌশলটির সংস্করণ যা ইতিমধ্যে প্রস্তাবিত হয়েছে:

values=(foo bar)
requestedValue=bar

requestedValue=${requestedValue##[[:space:]]}
requestedValue=${requestedValue%%[[:space:]]}
[[ "${values[@]/#/X-}" =~ "X-${requestedValue}" ]] || echo "Unsupported value"

এখানে যা ঘটছে তা হ'ল আপনি সমর্থিত মানগুলির পুরো অ্যারেটিকে শব্দের মধ্যে প্রসারিত করছেন এবং একটি নির্দিষ্ট স্ট্রিংকে এই ক্ষেত্রে "এক্স-" প্রিপেন্ড করছেন, এবং প্রতিটিটির জন্য অনুরোধকৃত মানটি করছেন। যদি এটি সত্যই অ্যারেতে অন্তর্ভুক্ত থাকে তবে ফলস্বরূপ স্ট্রিংটি ফলাফল প্রাপ্ত টোকেনগুলির একটির সাথে সর্বাধিক মিলবে বা বিপরীতে কিছুই নয়। পরের ক্ষেত্রে || অপারেটর ট্রিগার এবং আপনি জানেন যে আপনি একটি অসমর্থিত মান নিয়ে কাজ করছেন। সর্বোপরি অনুরোধকৃত মানটি স্ট্যান্ডার্ড শেল স্ট্রিং ম্যানিপুলেশনের মাধ্যমে সমস্ত নেতৃস্থানীয় এবং অনুসরণযোগ্য শ্বেতস্পেস ছিনিয়ে নেওয়া হয়।

এটি পরিচ্ছন্ন এবং মার্জিত, আমি বিশ্বাস করি, যদিও আপনার সমর্থিত মূল্যবোধের অ্যারেটি যদি বিশেষত বড় হয় তবে এটি কতটা পারফর্মেন্ট হতে পারে তা সম্পর্কে আমি খুব বেশি নিশ্চিত নই।


-1

এই সমস্যাটি সম্পর্কে আমার গ্রহণযোগ্যতা এখানে। সংক্ষিপ্ত সংস্করণটি এখানে:

function arrayContains() {
        local haystack=${!1}
        local needle="$2"
        printf "%s\n" ${haystack[@]} | grep -q "^$needle$"
}

এবং দীর্ঘ সংস্করণ, যা আমি মনে করি এটি চোখের চেয়ে অনেক সহজ।

# With added utility function.
function arrayToLines() {
        local array=${!1}
        printf "%s\n" ${array[@]}
}

function arrayContains() {
        local haystack=${!1}
        local needle="$2"
        arrayToLines haystack[@] | grep -q "^$needle$"
}

উদাহরণ:

test_arr=("hello" "world")
arrayContains test_arr[@] hello; # True
arrayContains test_arr[@] world; # True
arrayContains test_arr[@] "hello world"; # False
arrayContains test_arr[@] "hell"; # False
arrayContains test_arr[@] ""; # False

আমি এত দিন বাশ ব্যবহার করছি না যে উত্তরগুলি বুঝতে আমার খুব কষ্ট হয়েছে, বা আমি নিজে যা লিখেছিলাম তাও :) আমি বিশ্বাস করতে পারি না যে এই প্রশ্নটি এখনও এই সময়ের পরেও তৎপরতা পাচ্ছে :)
পাওলো টেডেসকো

কি হবে test_arr=("hello" "world" "two words")?
কিওয়ার্টি

-1

আমার কেস ছিল যে আমাকে অন্য স্ক্রিপ্ট / কমান্ড দ্বারা উত্পাদিত আইডির তালিকায় কোনও আইডি রয়েছে কিনা তা পরীক্ষা করে দেখতে হয়েছিল। আমার জন্য নিম্নলিখিত কাজ করেছেন:

# the ID I was looking for
ID=1

# somehow generated list of IDs
LIST=$( <some script that generates lines with IDs> )
# list is curiously concatenated with a single space character
LIST=" $LIST "

# grep for exact match, boundaries are marked as space
# would therefore not reliably work for values containing a space
# return the count with "-c"
ISIN=$(echo $LIST | grep -F " $ID " -c)

# do your check (e. g. 0 for nothing found, everything greater than 0 means found)
if [ ISIN -eq 0 ]; then
    echo "not found"
fi
# etc.

আপনি এটির মতো এটি সংক্ষিপ্ত / সংক্ষিপ্ত করতেও পারেন:

if [ $(echo " $( <script call> ) " | grep -F " $ID " -c) -eq 0 ]; then
    echo "not found"
fi

আমার ক্ষেত্রে, আমি আইডিগুলির তালিকার জন্য কিছু জেএসএন ফিল্টার করতে জিকিউ চালিয়ে যাচ্ছিলাম এবং পরে আমার আইডি এই তালিকায় রয়েছে কিনা তা পরীক্ষা করে দেখতে হয়েছিল এবং এটি আমার পক্ষে সবচেয়ে ভাল কাজ করেছে। এটি টাইপের ম্যানুয়ালি তৈরি অ্যারেগুলির জন্য কাজ করবে না LIST=("1" "2" "4")তবে নতুন লাইন দ্বারা পৃথক স্ক্রিপ্ট আউটপুট নিয়ে কাজ করবে।


PS: একটি উত্তর মন্তব্য করতে পারেনি কারণ আমি তুলনামূলকভাবে নতুন ...


-2

প্রদত্ত মান অ্যারেতে রয়েছে কিনা তা নিম্নলিখিত কোডটি পরীক্ষা করে এটির শূন্য-ভিত্তিক অফসেটটি প্রদান করে:

A=("one" "two" "three four")
VALUE="two"

if [[ "$(declare -p A)" =~ '['([0-9]+)']="'$VALUE'"' ]];then
  echo "Found $VALUE at offset ${BASH_REMATCH[1]}"
else
  echo "Couldn't find $VALUE"
fi

ম্যাচটি সম্পূর্ণ মানগুলিতে সম্পন্ন হয়, সুতরাং VALUE = "তিন" সেট করা মিলবে না।


-2

আপনি পুনরাবৃত্তি করতে না চাইলে এটি অনুসন্ধানের উপযুক্ত হতে পারে:

#!/bin/bash
myarray=("one" "two" "three");
wanted="two"
if `echo ${myarray[@]/"$wanted"/"WAS_FOUND"} | grep -q "WAS_FOUND" ` ; then
 echo "Value was found"
fi
exit

স্নিপেট: http://www.thegeekstuff.com/2010/06/bash-array-tutorial/ থেকে রূপান্তরিত হয়েছে বলে আমি মনে করি এটি বেশ চালাক।

সম্পাদনা: আপনি সম্ভবত ঠিক করতে পারেন:

if `echo ${myarray[@]} | grep -q "$wanted"` ; then
echo "Value was found"
fi

তবে পরেরটি কেবল তখনই কাজ করে যদি অ্যারেটিতে স্বতন্ত্র মান থাকে। "143" এ 1 এর জন্য অনুসন্ধান করা মিথ্যা ধনাত্মক, মিথথিক্স দেবে।


-2

কিছুটা দেরি হলেও আপনি এটি ব্যবহার করতে পারেন:

#!/bin/bash
# isPicture.sh

FILE=$1
FNAME=$(basename "$FILE") # Filename, without directory
EXT="${FNAME##*.}" # Extension

FORMATS=(jpeg JPEG jpg JPG png PNG gif GIF svg SVG tiff TIFF)

NOEXT=( ${FORMATS[@]/$EXT} ) # Formats without the extension of the input file

# If it is a valid extension, then it should be removed from ${NOEXT},
#+making the lengths inequal.
if ! [ ${#NOEXT[@]} != ${#FORMATS[@]} ]; then
    echo "The extension '"$EXT"' is not a valid image extension."
    exit
fi

-2

আমি এইটির সাথে এসেছি, যা কেবল zsh এ কাজ করতে দেখা যায়, তবে আমি মনে করি সাধারণ পদ্ধতিটি খুব সুন্দর।

arr=( "hello world" "find me" "what?" )
if [[ "${arr[@]/#%find me/}" != "${arr[@]}" ]]; then
    echo "found!"
else
    echo "not found!"
fi

আপনি প্রতিটি উপাদান থেকে আপনার প্যাটার্নটি কেবল তখনই শুরু করেন ${arr[@]/#pattern/}বা এটি দিয়ে শেষ ${arr[@]/%pattern/}হয়। এই দুটি বিকল্প ব্যাশে কাজ করে তবে উভয় একই সময়ে${arr[@]/#%pattern/} ব্যাশে কাজ কেবল zsh এ কাজ করে।

যদি পরিবর্তিত অ্যারেটি মূলের সমান হয়, তবে এতে উপাদানটি থাকে না।

সম্পাদনা:

এই ব্যাশে কাজ করে:

 function contains () {
        local arr=(${@:2})
        local el=$1
        local marr=(${arr[@]/#$el/})
        [[ "${#arr[@]}" != "${#marr[@]}" ]]
    }

প্রতিস্থাপনের পরে এটি উভয় অ্যারের দৈর্ঘ্যের তুলনা করে। অবশ্যই অ্যারেতে উপাদান থাকে তবে প্রতিস্থাপন এটি পুরোপুরি মুছে ফেলবে এবং গণনা পৃথক হবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.