The easiest way to check an index or key in an array?

Via:

set -o nounset 

1) The presence of an indexed array, such as:

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

What is the shortest way to check if item 1 is installed?
I sometimes use the following:

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

I would like to know if there is a preferred one.

2) How to deal with inconsistent indices?

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

How to quickly check that "51" is already installed, for example?

3) How to deal with associative arrays?

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

How to quickly check that "key2" is already in use, for example?

thank

EDITING
It seems to me the easiest way:

 if test "${myArray['key_or_index']+isset}" then echo "yes" else echo "no" fi; 

This works for both indexed and associative arrays. Errors are not displayed with the -o noun set.
Thanks to DoubleDown for the title.

+67
arrays bash indexing key
Nov 04
source share
7 answers

To check if an element is set (applies to both indexed and associative arrays)

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

In principle, that ${array[key]+abc} is

  • If array[key] set, return abc
  • If array[key] not set, do not return anything




References:
  • See Enhancing Options in the Bash Guide and a small note.

    if the colon is omitted, the operator only checks for the existence of [parameter]

  • This answer is actually adapted from the answers to this SO question: How to determine if a line is defined in the Bash script shell ?




Wrapper Function:

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

for example

 if ! exists key in array; then echo "No such array element"; fi 
+100
Nov 04 '12 at 18:25
source share

From man bash , conditional expressions:

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

example:

 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 

This will show that foo [bar] and foo [baz] are set (even if the latter is set to empty), but foo [quux] is not.

+17
Jul 29 '17 at 5:00
source share

Unfortunately, bash does not allow breaking betwen into an empty and undefined variable.

But there are several ways:

 $ 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 

(Do not answer)

And for an associative array you can use the same thing:

 $ 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 

You can do this work without using external tools (no printf | grep as pure bash), and why not, build checkIfExist () as a new bash function:

 $ 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 

or even create a new getIfExist bash function that returns the desired value and exits with a false result code if the desired value does not exist:

 $ 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 
+6
Nov 04 '12 at 3:15
source share

tested in 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 
+5
Nov 13 '15 at 3:28
source share

This is the easiest way I've found for scripts.

<search> is the string you want to find, ASSOC_ARRAY name of the variable containing your associative array.

Depends on what you want to achieve:

exist:

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

key missing:

 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 

value does not exist:

 if ! grep -qe "<search>" <(echo "${ASSOC_ARRAY[@]}"); then echo value not present; fi 
+1
Aug 15 '16 at
source share

I wrote a function to check if a key exists in an array in 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 } 

Example

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

Tested with GNU bash, version 4.1.5 (1) -release (i486-pc-linux-gnu)

+1
Feb 22 '17 at 10:45
source share

What about the -z test and operator :- ?

For example, this script:

 #!/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 

Print:

 ABC is set DEF is set 
0
Jul 01 '19 at 19:25
source share



All Articles