Yanıtlar:
Bash 4'te ilişkilendirilebilir diziler kullanabilirsiniz:
# 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
Diziyi başlangıçta ayarlamak için doğrudan atamalar da yapabilirsiniz:
array[foo]=1
array[bar]=1
# etc.
veya bu şekilde:
array=([foo]=1 [bar]=1 [baz]=1)
${array[$test1]}
basit ama bir sorunu var: set -u
"sınırsız değişken" alacağınız için komut dosyalarınızda (önerilen) kullanırsanız çalışmaz .
Eski bir soru, ama ben basit çözüm henüz görünmüyor ne düşünüyorum: test ${array[key]+_}
. Misal:
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"
Çıktılar:
a is set
b is set
Bu eser kontrol nasıl çalıştığını görmek için bu .
env
, takma adlarda, programlarda ve "test" adını benimsemiş olabilecek diğer işlevlerdeki belirsizlikleri önlemek için kullanmanızı önerir. Yukarıdaki gibi env test ${xs[a]+_} && echo "a is set"
. Bu işlevi çift parantez kullanarak da alabilirsiniz, aynı hile sonra null olup olmadığını kontrol edebilirsiniz:[[ ! -z "${xs[b]+_}" ]] && echo "b is set"
[[ ${xs[b]+set} ]]
İlişkilendirilebilir bir dizinin bir öğesinin (ayarlanmadı) var olup olmadığını test etmenin bir yolu vardır, bu boştan farklıdır:
isNotSet() {
if [[ ! ${!1} && ${!1-_} ]]
then
return 1
fi
}
Sonra kullanın:
declare -A assoc
KEY="key"
isNotSet assoc[${KEY}]
if [ $? -ne 0 ]
then
echo "${KEY} is not set."
fi
if ! some_check then return 1
= olduğuna dikkat edin some_check
. Yani: isNotSet() { [[ ... ]] }
. Aşağıdaki çözümümü kontrol edin, basit bir kontrolle yapabilirsiniz.
Dizinin içeriğini grep'e ayırarak bir girişin olup olmadığını görebilirsiniz.
printf "%s\n" "${mydata[@]}" | grep "^${val}$"
Ayrıca bir eşleşmenin satır numarasını döndüren grep -n ile bir girdinin dizinini de alabilirsiniz (sıfır tabanlı dizin elde etmek için 1 çıkarmayı unutmayın) Bu çok büyük diziler dışında oldukça hızlı olacaktır.
# 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
açıklama:
$( ... )
bir komutun bir değişkeni çıktısını yakalamak için ters tırnak kullanmakla aynıdır printf
verilerimi satır başına bir öğe çıktılar @
bunun yerine tüm alıntılar *.
"merhaba dünya" nın 2 satıra bölünmesini önler)grep
tam dize arar: ^
ve $
satırın başlangıcını ve sonunu eşleştirirgrep -n
4 numaralı hat # ile döner: merhaba dünya grep -m 1
sadece ilk eşleşmeyi bulurcut
sadece satır numarasını çıkarır Elbette çıkartmayı komuta katlayabilirsiniz. Ama sonra -1 için eksik olup olmadığını test edin:
ix=$(( $( printf "%s\n" "${mydata[@]}" | grep -n -m 1 "^${val}$" | cut -d ":" -f1 ) - 1 ))
if [[ $ix == -1 ]]; then echo missing; else ... fi
$(( ... ))
tam sayı aritmetiği yaparDizide çok sınırlı veri olmadığı sürece döngü olmadan düzgün yapabileceğinizi sanmıyorum .
İşte basit bir varyant, bu "Super User"
dizide var olduğunu doğru söyleyecektir . Ama aynı zamanda "uper Use"
dizide olduğunu da söyleyebilirim .
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
Sorun diziyi döngü yanı sıra (düşünebileceğim) çapa eklemek için kolay bir yolu olmasıdır. Diziye koymadan önce ekleyemezseniz ...
grep "\b$FINDME\b"
) güzel bir çözümdür . Muhtemelen boşlukları olmayan alfanümerik olmayan sabitlerle çalışabilir, "(^| )$FINDME(\$| )"
(veya bunun gibi bir şey ... regexp
#!/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
. Şerefe
${ARRAY[@]}
kullanılmalıdır.