Menggunakan:
set -o nounset
Memiliki array terindeks seperti:
myArray=( "red" "black" "blue" )
Apa cara terpendek untuk memeriksa apakah elemen 1 disetel?
Saya terkadang menggunakan yang berikut:test "${#myArray[@]}" -gt "1" && echo "1 exists" || echo "1 doesn't exist"
Saya ingin tahu apakah ada yang lebih disukai.
Bagaimana cara menangani indeks non-berturut-turut?
myArray=() myArray[12]="red" myArray[51]="black" myArray[129]="blue"
Bagaimana cara cek cepat yang
51
sudah diatur misalnya?Bagaimana menangani array asosiatif?
declare -A myArray myArray["key1"]="red" myArray["key2"]="black" myArray["key3"]="blue"
Bagaimana cara cek cepat yang
key2
sudah digunakan misalnya?
+abc
,[ ${array[key]} ]
akan dievaluasi ke false jika elemen memang disetel tetapi ke nilai kosong, jadi ini sebenarnya menguji nilai non-kekosongan daripada keberadaan kunci.+abc
juga gagal saatarray[key]
tidak disetel danset -u
efektif.Dari man bash , ekspresi bersyarat:
-v varname True if the shell variable varname is set (has been assigned a value).
contoh:
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
Ini akan menunjukkan bahwa foo [bar] dan foo [baz] disetel (meskipun yang terakhir disetel ke nilai kosong) dan foo [quux] tidak.
sumber
set -u
, mengapa[[ -v "${foo[bar]}" ]]
menghasilkan kesalahan variabel tak terikat jikabar
tidak ada di kamus? Bekerja dengan baik tanpa${}
; Saya hanya terbiasa menggunakannya untuk semuanya secara default."${foo[bar]}"
mengevaluasi variabel array terlebih dahulu, jadi[[ -v
perintah menguji variabel dengan nama nilai ituJawaban baru
Dari versi 4.2 dari pesta(dan yang lebih baru), ada
-v
opsi baru untuktest
perintah bawaan.Dari versi 4.3, pengujian ini dapat menangani elemen array.
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
Ini bekerja dengan array asosiatif dengan cara yang sama:
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
Dengan sedikit perbedaan:
Dalam array biasa, variabel antara tanda kurung (
[i]
) adalah bilangan bulat, jadi simbol dolar ($
) tidak diperlukan, tetapi untuk array asosiatif, karena kunci adalah kata,$
diperlukan ([$i]
)!Jawaban lama untuk pesta sebelum V4.2
Sayangnya, bash tidak memberikan cara untuk membuat perbedaan antara variabel kosong dan variabel tidak terdefinisi .
Tetapi ada beberapa cara:
$ 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
(tidak memberikan jawaban)
Dan untuk array asosiatif, Anda bisa menggunakan yang sama:
$ 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
Anda dapat melakukan pekerjaan tersebut tanpa memerlukan alat eksternal (tidak ada printf | grep sebagai pure bash ), dan mengapa tidak, buat checkIfExist () sebagai fungsi bash baru:
$ 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
atau bahkan buat fungsi bash getIfExist baru yang mengembalikan nilai yang diinginkan dan keluar dengan kode hasil palsu jika nilai yang diinginkan tidak ada:
$ 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
sumber
bash 4.2.46
. Berhasilbash 4.4.12
.-v
pilihantest
ataugetIfExist
fungsi?-v
telah ditambahkan ke bash-4.2 TAPI dukungan untuk memeriksa indeks array tidak ditambahkan hingga bash-4.3.diuji di bash 4.3.39 (1) -release
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
sumber
+
perluasan parameter untuk mengganti nilai kosong dengan beberapa placeholder seperti garis bawah. Misalnyadeclare -A a[x]=;[[ ${a[x]} ]];echo $?
cetakan1
, tapideclare -A a[x]=;[[ ${a[x]+_} ]];echo $?
cetakan0
.Bagaimana dengan
-z
tes dan:-
operator?Misalnya, skrip ini:
#!/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
Cetakan:
ABC is set DEF is set
sumber
Ini adalah cara termudah yang saya temukan untuk skrip.
<search>
adalah string yang ingin Anda temukan,ASSOC_ARRAY
nama variabel yang menampung array asosiatif Anda.Bergantung pada apa yang ingin Anda capai:
kunci ada :
if grep -qe "<search>" <(echo "${!ASSOC_ARRAY[@]}"); then echo key is present; fi
kunci tidak ada :
if ! grep -qe "<search>" <(echo "${!ASSOC_ARRAY[@]}"); then echo key not present; fi
nilai ada :
if grep -qe "<search>" <(echo "${ASSOC_ARRAY[@]}"); then echo value is present; fi
nilai tidak ada :
if ! grep -qe "<search>" <(echo "${ASSOC_ARRAY[@]}"); then echo value not present; fi
sumber
Saya menulis fungsi untuk memeriksa apakah ada kunci dalam array di Bash:
# 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 }
Contoh
declare -A my_array my_array['foo']="bar" if [[ "$(array_key_exists 'my_array' 'foo'; echo $?)" = "0" ]]; then echo "OK" else echo "ERROR" fi
Diuji dengan GNU bash, versi 4.1.5 (1) -release (i486-pc-linux-gnu)
sumber