কোন অ্যারেতে কোনও সূচক বা কোনও কী পরীক্ষা করার সহজ উপায়?


92

ব্যবহার:

set -o nounset
  1. একটি সূচকযুক্ত অ্যারে থাকার মতো:

    myArray=( "red" "black" "blue" )
    

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

    test "${#myArray[@]}" -gt "1" && echo "1 exists" || echo "1 doesn't exist"
    

    আমি জানতে চাই যে সেখানে কোনও পছন্দসই আছে কিনা।

  2. অবিচ্ছিন্ন সূচকগুলি কীভাবে মোকাবেলা করতে হবে?

    myArray=()
    myArray[12]="red"
    myArray[51]="black"
    myArray[129]="blue"
    

    51ইতিমধ্যে উদাহরণস্বরূপ সেট করা কীভাবে দ্রুত চেক করবেন?

  3. সাহসী অ্যারেগুলি কীভাবে মোকাবেলা করবেন?

    declare -A myArray
    myArray["key1"]="red"
    myArray["key2"]="black"
    myArray["key3"]="blue"
    

    key2ইতিমধ্যে উদাহরণস্বরূপ ব্যবহৃত কীভাবে দ্রুত চেক করবেন?

উত্তর:


134

উপাদানটি সেট করা আছে কিনা তা পরীক্ষা করতে (ইনডেক্সড এবং এসোসিয়েটিভ অ্যারে উভয় ক্ষেত্রেই প্রযোজ্য)

[ ${array[key]+abc} ] && echo "exists"

মূলত যা হয় ${array[key]+abc}তা হচ্ছে

  • যদি array[key]সেট করা থাকে তবে ফিরে আসুনabc
  • যদি array[key]সেট না করা থাকে তবে কিছুই ফিরিয়ে দিন না


তথ্যসূত্র:

  1. দেখুন প্যারামিটার সম্প্রসারণ ব্যাশ ম্যানুয়াল এবং সামান্য নোট

    যদি কোলন বাদ দেওয়া হয় তবে অপারেটর কেবল [ পরামিতিটির ] অস্তিত্বের জন্য পরীক্ষা করে

  2. এই উত্তরটি আসলে এই এই প্রশ্নের উত্তরগুলির সাথে অভিযোজিত: বাশ শেল স্ক্রিপ্টে কোনও স্ট্রিং সংজ্ঞায়িত না হলে কীভাবে বলা যায় ?


একটি মোড়ক ফাংশন:

exists(){
  if [ "$2" != in ]; then
    echo "Incorrect usage."
    echo "Correct usage: exists {key} in {array}"
    return
  fi   
  eval '[ ${'$3'[$1]+muahaha} ]'  
}

উদাহরণ স্বরূপ

if ! exists key in array; then echo "No such array element"; fi 

আমি এইভাবে সমাধান করেছি: যদি পরীক্ষা "$ {myArray ['key_or_index'] + isset}"; তারপরে "হ্যাঁ" প্রতিধ্বনি করুন; অন্যথায় "না" প্রতিধ্বনি; ফাই এটি আমার কাছে সহজতম উপায় বলে মনে হচ্ছে এবং এটি সূচিবদ্ধ এবং মিশুক অ্যারেগুলিতে প্রযোজ্য। আপনাকে ধন্যবাদ
লুসা বোররিওন

4
@ ডাবলডাউন আপনি [$ ray অ্যারে [কী] + অ্যাবসি}] কীভাবে ব্যবহার করতে পারেন যদি [only ray অ্যারে [কী] + অ্যাবসি}] অস্তিত্ব না থাকে তবে কেবল কিছু করার জন্য ক্লজ?
ওলালা

4
এছাড়াও আপনি যখন দুর্ঘটনাক্রমে এনামুরেটেড অ্যারেটিকে সাহসী হিসাবে জিজ্ঞাসা করেন তখনও কাজ করে না।
টোমা জ্যাটো - মনিকা

4
@ দুআনেভ: ছাড়াই +abc, মিথ্যাটিকে [ ${array[key]} ]মূল্যায়ন করবে যদি উপাদানটি প্রকৃতপক্ষে সেট করা হয় তবে খালি মূল্য হিসাবে সেট করা হয়, সুতরাং এটি মূল কী অস্তিত্বের পরিবর্তে শূন্যতার মানটি পরীক্ষা করে।
musifhil

@ দুআনেভ +abcছাড়াও ব্যর্থ হয় যখন array[key]সেট না থাকে এবং set -uকার্যকর হয়।
ডিঙ-ই চেন

36

ম্যান বাশ থেকে , শর্তাধীন অভিব্যক্তি:

-v varname
              True if the shell variable varname is set (has been assigned a value).

উদাহরণ:

declare -A foo
foo[bar]="this is bar"
foo[baz]=""
if [[ -v "foo[bar]" ]] ; then
  echo "foo[bar] is set"
fi
if [[ -v "foo[baz]" ]] ; then
  echo "foo[baz] is set"
fi
if [[ -v "foo[quux]" ]] ; then
  echo "foo[quux] is set"
fi

এটি দেখায় যে foo [বার] এবং foo [বাজ] উভয়ই সেট করা আছে (যদিও পরবর্তীটি একটি খালি মান হিসাবে সেট করা থাকে) এবং foo [quux] নেই।


4
আমি তাড়াতাড়ি এক নজরে মিস করেছি; লক্ষ্য করুন যে টিপিক্যাল অ্যারে এক্সপেনশন সিনট্যাক্স ব্যবহার করা হয়নি।
নাথান চ্যাপেল

এর সাথে set -u, অভিধানে উপস্থিত না থাকলে কেন [[ -v "${foo[bar]}" ]]আনবাউন্ড ভেরিয়েবল ত্রুটি তৈরি barহয়? ছাড়া ভাল কাজ করে ${}; আমি কেবল এটি ডিফল্টরূপে প্রত্যেকটির জন্য ব্যবহার করতে অভ্যস্ত
bgfvdu3w

"${foo[bar]}"প্রথমে অ্যারে ভেরিয়েবলটি মূল্যায়ন করে, সুতরাং [[ -vকমান্ডটি সেই মানটির নামের সাথে একটি ভেরিয়েবলের জন্য পরীক্ষা করে
andysh

12

নতুন উত্তর

সংস্করণ থেকে 4.2 (এবং আরও নতুন), -vবিল্ট-ইন testকমান্ডের জন্য একটি নতুন বিকল্প রয়েছে ।

সংস্করণ ৪.৩ থেকে, এই পরীক্ষাটি অ্যারের উপাদানগুলিকে সম্বোধন করতে পারে।

array=([12]="red" [51]="black" [129]="blue")

for i in 10 12 30 {50..52} {128..131};do
    if [ -v array[i] ];then
        echo "Variable 'array[$i]' is defined"
    else
        echo "Variable 'array[$i]' not exist"
    fi
done
Variable 'array[10]' not exist
Variable 'array[12]' is defined
Variable 'array[30]' not exist
Variable 'array[50]' not exist
Variable 'array[51]' is defined
Variable 'array[52]' not exist
Variable 'array[128]' not exist
Variable 'array[129]' is defined
Variable 'array[130]' not exist
Variable 'array[131]' not exist

এই পদ্ধতিতে একইভাবে সহযোগী অ্যারেগুলি সহ :

declare -A aArray=([foo]="bar" [bar]="baz" [baz]=$'Hello world\041')

for i in alpha bar baz dummy foo test;do
    if [ -v aArray[$i] ];then
        echo "Variable 'aArray[$i]' is defined"
    else
        echo "Variable 'aArray[$i]' not exist"
    fi
done
Variable 'aArray[alpha]' not exist
Variable 'aArray[bar]' is defined
Variable 'aArray[baz]' is defined
Variable 'aArray[dummy]' not exist
Variable 'aArray[foo]' is defined
Variable 'aArray[test]' not exist

কিছুটা পার্থক্য সহ:
নিয়মিত অ্যারেগুলিতে, বন্ধনীগুলির মধ্যে পরিবর্তনশীল ( [i]) পূর্ণসংখ্যা হয়, সুতরাং ডলারের প্রতীক ( $) প্রয়োজন হয় না, তবে সহযোগী অ্যারেগুলির জন্য কী হিসাবে একটি শব্দ $প্রয়োজন ( [$i])!

জন্য পুরানো উত্তর ভি 4.2 এর পূর্বে

দুর্ভাগ্যক্রমে, বাশ পার্থক্যকে আলাদা করার কোনও উপায় দেয় না খালি এবং অনির্ধারিত পরিবর্তনশীল।

তবে কিছু উপায় আছে:

$ array=()
$ array[12]="red"
$ array[51]="black"
$ array[129]="blue"

$ echo ${array[@]}
red black blue

$ echo ${!array[@]}
12 51 129

$ echo "${#array[@]}"
3

$ printf "%s\n" ${!array[@]}|grep -q ^51$ && echo 51 exist
51 exist

$ printf "%s\n" ${!array[@]}|grep -q ^52$ && echo 52 exist

(কোন উত্তর দিন)

এবং সহযোগী অ্যারে জন্য, আপনি একই ব্যবহার করতে পারেন:

$ unset array
$ declare -A array
$ array["key1"]="red"
$ array["key2"]="black"
$ array["key3"]="blue"
$ echo ${array[@]}
blue black red

$ echo ${!array[@]}
key3 key2 key1

$ echo ${#array[@]}
3

$ set | grep ^array=
array=([key3]="blue" [key2]="black" [key1]="red" )

$ printf "%s\n" ${!array[@]}|grep -q ^key2$ && echo key2 exist || echo key2 not exist
key2 exist

$ printf "%s\n" ${!array[@]}|grep -q ^key5$ && echo key5 exist || echo key5 not exist
key5 not exist

আপনি বাহ্যিক সরঞ্জামগুলির প্রয়োজন ছাড়াই কাজটি করতে পারেন ( খাঁটি বাশ হিসাবে কোনও প্রিন্টফ | গ্রেপ নয়) এবং কেন নয়, নতুন বাশ ফাংশন হিসাবে চেকআইফএক্সজিস্ট () তৈরি করুন :

$ checkIfExist() {
    eval 'local keys=${!'$1'[@]}';
    eval "case '$2' in
        ${keys// /|}) return 0 ;;
        * ) return 1 ;;
      esac";
}

$ checkIfExist array key2 && echo exist || echo don\'t
exist

$ checkIfExist array key5 && echo exist || echo don\'t
don't

বা এমনকি একটি নতুন getIfExist বাশ ফাংশন তৈরি করুন যা কাঙ্ক্ষিত মানটি প্রত্যাবর্তন করে এবং পছন্দসই মান উপস্থিত না থাকলে মিথ্যা ফলাফল-কোড সহ প্রস্থান করুন:

$ getIfExist() {
    eval 'local keys=${!'$1'[@]}';
    eval "case '$2' in
        ${keys// /|}) echo \${$1[$2]};return 0 ;;
        * ) return 1 ;;
      esac";
}

$ getIfExist array key1
red
$ echo $?
0

$ # now with an empty defined value
$ array["key4"]=""
$ getIfExist array key4

$ echo $?
0
$ getIfExist array key5
$ echo $?
1

ঠিক আছে downvotes জন্য এই উত্তর v4.2 আগে পোস্ট করা হয়েছে ব্যাশ ! উত্তর সম্পাদিত!
এফ। হাউরি

কাজ করে না bash 4.2.46। কাজ করে bash 4.4.12
ইরফিত

@ নিবন্ধটি কি কাজ করে না? -vবিকল্প testবা getIfExistফাংশন?
এফ হাউরি

4
-vবাশ -৩.২-এ যোগ করা হয়েছিল কিন্তু অ্যারে সূচকগুলি পরীক্ষা করার জন্য বাশ -4 সমর্থন বাশ -৩.৩ অবধি যোগ করা হয়নি।
মিঃ স্পুর্যাটিক

4
@ মিঃ স্পুর্যাটিক মন্তব্যের জন্য ধন্যবাদ!
এফ। হাউরি

5

বাশ ৪.৩.৩৯ (১) -তে পরীক্ষা করা হয়েছে - দয়া করে

declare -A fmap
fmap['foo']="boo"

key='foo'
# should echo foo is set to 'boo'
if [[ -z "${fmap[${key}]}" ]]; then echo "$key is unset in fmap"; else echo "${key} is set to '${fmap[${key}]}'"; fi
key='blah'
# should echo blah is unset in fmap
if [[ -z "${fmap[${key}]}" ]]; then echo "$key is unset in fmap"; else echo "${key} is set to '${fmap[${key}]}'"; fi

যখন ব্যর্থ হয় কীটির মান খালি স্ট্রিং হয়। ওয়ার্কআরআউন্ড হিসাবে আপনি +কোনও খালি মানটিকে আন্ডারস্কোরের মতো কিছু স্থানধারীর সাথে প্রতিস্থাপন করতে প্যারামিটার সম্প্রসারণ ব্যবহার করতে পারেন । উদাহরণস্বরূপ declare -A a[x]=;[[ ${a[x]} ]];echo $?প্রিন্ট 1, তবে declare -A a[x]=;[[ ${a[x]+_} ]];echo $?প্রিন্টগুলি 0
নিসেতামা

3

একটি -zপরীক্ষা এবং :-অপারেটর সম্পর্কে কি ?

উদাহরণস্বরূপ, এই স্ক্রিপ্ট:

#!/usr/bin/env bash

set -e
set -u

declare -A sample

sample["ABC"]=2
sample["DEF"]=3

if [[ ! -z "${sample['ABC']:-}" ]]; then
  echo "ABC is set"
fi

if [[ ! -z "${sample['DEF']:-}" ]]; then
  echo "DEF is set"
fi

if [[ ! -z "${sample['GHI']:-}" ]]; then
  echo "GHI is set"
fi

মুদ্রণ:

ABC is set
DEF is set

দুর্দান্ত কমপ্যাক্ট সমাধান যা খালি স্ট্রিংয়ের জন্য প্রত্যাশার প্রতিক্রিয়া জানায়
রায়ান ডুগান

1

স্ক্রিপ্টগুলির জন্য এটি সবচেয়ে সহজ উপায়।

<search>আপনি যে স্ট্রিংটি সন্ধান করতে চান তা ASSOC_ARRAYহ'ল আপনার এসোসিয়েটিভ অ্যারে ধারণ করে চলকটির নাম।

আপনি কী অর্জন করতে চান তার উপর নির্ভর করুন:

কী বিদ্যমান :

if grep -qe "<search>" <(echo "${!ASSOC_ARRAY[@]}"); then echo key is present; fi

কী বিদ্যমান নেই :

if ! grep -qe "<search>" <(echo "${!ASSOC_ARRAY[@]}"); then echo key not present; fi

মান বিদ্যমান :

if grep -qe "<search>" <(echo "${ASSOC_ARRAY[@]}"); then echo value is present; fi

মান বিদ্যমান নেই :

if ! grep -qe "<search>" <(echo "${ASSOC_ARRAY[@]}"); then echo value not present; fi

1

বাশের একটি অ্যারেতে কী উপস্থিত রয়েছে কিনা তা পরীক্ষা করতে আমি একটি ফাংশন লিখেছিলাম:

# Check if array key exists
# Usage: array_key_exists $array_name $key
# Returns: 0 = key exists, 1 = key does NOT exist
function array_key_exists() {
    local _array_name="$1"
    local _key="$2"
    local _cmd='echo ${!'$_array_name'[@]}'
    local _array_keys=($(eval $_cmd))
    local _key_exists=$(echo " ${_array_keys[@]} " | grep " $_key " &>/dev/null; echo $?)
    [[ "$_key_exists" = "0" ]] && return 0 || return 1
}

উদাহরণ

declare -A my_array
my_array['foo']="bar"

if [[ "$(array_key_exists 'my_array' 'foo'; echo $?)" = "0" ]]; then
    echo "OK"
else
    echo "ERROR"
fi

জিএনইউ ব্যাশ, সংস্করণ 4.1.5 (1) -রেলিজ (i486-পিসি-লিনাক্স-গনু) এর সাথে পরীক্ষিত

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