Самый простой способ проверить наличие индекса или ключа в массиве?
использование:
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' уже используется, например?
Спасибо
редактировать
Самый простой способ мне кажется:
if test "${myArray['key_or_index']+isset}"
then
echo "yes"
else
echo "no"
fi;
это работает как для индексированных, так и для ассоциативных массивов. Нет ошибок, показанных с set-o nounset.
Благодаря ощути волнующую развлечений Для из Headup.
6 ответов:
чтобы проверить, установлен ли элемент (применяется как к индексированному, так и к ассоциативному массиву)
[ ${array[key]+abc} ] && echo "exists"в основном то, что
${array[key]+abc}это
- если
array[key]установлено, возвратитьabc- если
array[key]не установлен, ничего не возвращает
Ссылки на литературу:
посмотреть Расширения Параметр в руководстве Bash и маленьком примечании
если двоеточие опущено, то оператор проверяет только на существование [of параметр]
этот ответ фактически адаптирован из ответов на этот вопрос SO:как сказать, если строка не определена в скрипте оболочки bash?
функции-обертки:
exists(){ if [ "" != in ]; then echo "Incorrect usage." echo "Correct usage: exists {key} in {array}" return fi eval '[ ${''[]+muahaha} ]' }if ! exists key in array; then echo "No such array element"; fi
к сожалению, Баш не дают никакого способа сделать разницу между пустой и неопределено переменной.
но есть несколько способов:
$ 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вы можете выполнить эту работу без необходимости внешних инструментов (без printf / grep as чисто Баш), а почему бы не построить checkIfExist () как новый Баш функция:
$ checkIfExist() { eval 'local keys=${!''[@]}'; eval "case '' 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 функция bash, которая возвращает желаемое значение и выходит с ложным результатом-кодом, если желаемое значение не существует:
$ getIfExist() { eval 'local keys=${!''[@]}'; eval "case '' in ${keys// /|}) echo ${[]};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
от man bash, условные выражения:
-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[bar] и foo[baz] установлены (даже если последнее установлено в пустое значение), а foo[quux] - нет.
протестировано в 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
это самый простой способ я нашел для скриптов.
<search>- это строка, которую нужно найти,ASSOC_ARRAYимя переменной, содержащей ассоциативный массив.Dependign от того, что вы хотите достичь:
ключ:
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
Я написал функцию, чтобы проверить, существует ли ключ в массиве в 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="" local _key="" 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протестировано с GNU bash, версия 4.1.5 (1)-release (i486-pc-linux-gnu)
Comments