Jawaban:
Di Bash 4, Anda dapat menggunakan array asosiatif:
# set up array of constants
declare -A array
for constant in foo bar baz
do
array[$constant]=1
done
# test for existence
test1="bar"
test2="xyzzy"
if [[ ${array[$test1]} ]]; then echo "Exists"; fi # Exists
if [[ ${array[$test2]} ]]; then echo "Exists"; fi # doesn't
Untuk mengatur array pada awalnya Anda juga bisa melakukan tugas langsung:
array[foo]=1
array[bar]=1
# etc.
atau dengan cara ini:
array=([foo]=1 [bar]=1 [baz]=1)
${array[$test1]}
sederhana tetapi memiliki masalah: itu tidak akan berfungsi jika Anda menggunakan set -u
skrip Anda (yang disarankan), karena Anda akan mendapatkan "variabel tidak terikat".
set -u
: davidpashley.com/articles/writing-robust-shell-scripts.html , blog.hashbang0.com/2010/05/18/robust-bash-scripts-part-one , openews.net/2012/bash- script-to-write-robust .
Ini adalah pertanyaan lama, tapi saya pikir apa solusi yang paling sederhana belum muncul belum: test ${array[key]+_}
. Contoh:
declare -A xs=([a]=1 [b]="")
test ${xs[a]+_} && echo "a is set"
test ${xs[b]+_} && echo "b is set"
test ${xs[c]+_} && echo "c is set"
Output:
a is set
b is set
Untuk melihat bagaimana ini bekerja, periksa ini .
env
untuk menghindari ambiguitas dalam alias, prog dan fungsi lain yang mungkin telah mengadopsi nama "test". Seperti di atas env test ${xs[a]+_} && echo "a is set"
. Anda juga bisa mendapatkan fungsionalitas ini menggunakan kurung ganda, trik yang sama kemudian memeriksa null:[[ ! -z "${xs[b]+_}" ]] && echo "b is set"
[[ ${xs[b]+set} ]]
Ada cara untuk menguji apakah elemen array asosiatif ada (tidak disetel), ini berbeda dengan kosong:
isNotSet() {
if [[ ! ${!1} && ${!1-_} ]]
then
return 1
fi
}
Kemudian gunakan:
declare -A assoc
KEY="key"
isNotSet assoc[${KEY}]
if [ $? -ne 0 ]
then
echo "${KEY} is not set."
fi
if ! some_check then return 1
= some_check
. Jadi: isNotSet() { [[ ... ]] }
. Periksa solusi saya di bawah ini, Anda dapat melakukannya dengan cek sederhana.
Anda dapat melihat apakah ada entri dengan memiparkan konten array ke grep.
printf "%s\n" "${mydata[@]}" | grep "^${val}$"
Anda juga bisa mendapatkan indeks entri dengan grep -n, yang mengembalikan nomor baris pertandingan (ingat untuk mengurangi 1 untuk mendapatkan indeks berbasis nol) Ini akan cukup cepat kecuali untuk array yang sangat besar.
# given the following data
mydata=(a b c "hello world")
for val in a c hello "hello world"
do
# get line # of 1st matching entry
ix=$( printf "%s\n" "${mydata[@]}" | grep -n -m 1 "^${val}$" | cut -d ":" -f1 )
if [[ -z $ix ]]
then
echo $val missing
else
# subtract 1. Bash arrays are zero-based, but grep -n returns 1 for 1st line, not 0
echo $val found at $(( ix-1 ))
fi
done
a found at 0
c found at 2
hello missing
hello world found at 3
penjelasan:
$( ... )
sama dengan menggunakan backticks untuk menangkap output dari suatu perintah ke dalam variabel printf
output mydata satu elemen per baris @
alih - alih *.
ini, hindari membagi "hello world" menjadi 2 baris)grep
mencari string yang tepat: ^
dan $
mencocokkan awal dan akhir barisgrep -n
mengembalikan baris #, dalam bentuk 4: hello world grep -m 1
menemukan kecocokan pertama sajacut
ekstrak hanya nomor baris Anda tentu saja dapat melipat pengurangan menjadi perintah. Tapi kemudian uji -1 untuk hilang:
ix=$(( $( printf "%s\n" "${mydata[@]}" | grep -n -m 1 "^${val}$" | cut -d ":" -f1 ) - 1 ))
if [[ $ix == -1 ]]; then echo missing; else ... fi
$(( ... ))
tidak bilangan bulat aritmatikaSaya tidak berpikir Anda bisa melakukannya dengan benar tanpa perulangan kecuali Anda memiliki data yang sangat terbatas dalam array.
Berikut adalah satu varian sederhana, ini akan dengan benar mengatakan bahwa "Super User"
ada dalam array. Tetapi itu juga akan mengatakan bahwa "uper Use"
ada dalam array.
MyArray=('Super User' 'Stack Overflow' 'Server Fault' 'Jeff' );
FINDME="Super User"
FOUND=`echo ${MyArray[*]} | grep "$FINDME"`
if [ "${FOUND}" != "" ]; then
echo Array contains: $FINDME
else
echo $FINDME not found
fi
#
# If you where to add anchors < and > to the data it could work
# This would find "Super User" but not "uper Use"
#
MyArray2=('<Super User>' '<Stack Overflow>' '<Server Fault>' '<Jeff>' );
FOUND=`echo ${MyArray2[*]} | grep "<$FINDME>"`
if [ "${FOUND}" != "" ]; then
echo Array contains: $FINDME
else
echo $FINDME not found
fi
Masalahnya adalah bahwa tidak ada cara mudah untuk menambahkan jangkar (yang dapat saya pikirkan) selain perulangan melalui array. Kecuali jika Anda dapat menambahkannya sebelum memasukkannya ke dalam array ...
grep "\b$FINDME\b"
). Mungkin bisa bekerja dengan konstanta non-alfanumerik yang tidak memiliki spasi, dengan "(^| )$FINDME(\$| )"
(atau sesuatu seperti itu ... Saya tidak pernah bisa belajar apa rasa penggunaan regexp grep.)
#!/bin/bash
function in_array {
ARRAY=$2
for e in ${ARRAY[*]}
do
if [[ "$e" == "$1" ]]
then
return 0
fi
done
return 1
}
my_array=(Drupal Wordpress Joomla)
if in_array "Drupal" "${my_array[*]}"
then
echo "Found"
else
echo "Not found"
fi
in_array
. Cheers
${ARRAY[@]}
harus digunakan.