I have an array of animals:
declare -A animals=()
animals+=([horse])
and I want to check if an animal exists or not:
if [ -z "$animals[horse]"]; then
echo "horse exists";
fi
but this does not work.
I have an array of animals:
declare -A animals=()
animals+=([horse])
and I want to check if an animal exists or not:
if [ -z "$animals[horse]"]; then
echo "horse exists";
fi
but this does not work.
In bash
4.3, the -v
operator can be applied to arrays.
declare -A animals
animals[horse]=neigh
# Fish are silent
animals[fish]=
[[ -v animals[horse] ]] && echo "horse exists"
[[ -v animals[fish] ]] && echo "fish exists"
[[ -v animals[unicorn] ]] || echo "unicorn does not exist"
In prior versions, you would need to be more careful distinguishing between the key not existing and the key referring to any empty string.
animal_exists () {
# If the given key maps to a non-empty string (-n), the
# key obviously exists. Otherwise, we need to check if
# the special expansion produces an empty string or an
# arbitrary non-empty string.
[[ -n ${animals[$1]} || -z ${animals[$1]-foo} ]]
}
animal_exists horse && echo "horse exists"
animal_exists fish && echo "fish exists"
animal_exists unicorn || echo "unicorn does not exist"
There are several typos in your script
When I run it as it is, I get the following error messages from BASH:
1. animals: [horse]: must use subscript when assigning associative array
2. [: missing `]'
The first one says that if you want to use horse
as an index to an associative array, you have to assign a value to it. An empty value (null) is ok.
-animals+=([horse])
+animals+=([horse]=)
The second message says that you need to separate the value you want to test and the bracket, as square bracket is considered a part of the value if not separated by spaces
-if [ -z "$animals[horse]"]; then
+if [ -z "$animals[horse]" ]; then
Finally, an element in an associative array exists when there is a value assigned to it (even if this value is null). As the question of testing if an array value is set has already been answered on this site, we can borrow the solution
-if [ -z "$animals[horse]"]; then
+if [ -n "${animals[horse]+1}" ]; then
For your convinience here is the complete script:
declare -A animals=()
animals+=([horse]=)
if [ -n "${animals[horse] + 1}" ]; then
echo "horse exists";
fi
In BASH you can do:
declare -A animals=()
animals+=([horse]=)
[[ "${animals[horse]+foobar}" ]] && echo "horse exists"
"${animals[horse]+foobar}"
returns foobar
if horse
is a valid index in array otherwise it returns nothing.
A bit old, but came up when I was searching for an answer, my system doesnt have bash 4.3
and I was specifically concerned about animals[horse-2]
example
Another way you can do it is by dumping the contents out of the the array and then checking if the substring matches -
declare -A animals
animals[horse-2]=neigh-2
animals[dog]=woof
animals_as_string=$(declare -p animals)
other_animals="horse-2 moose cow"
for animal in $other_animals
do
if [[ "$animal" == *$animals_as_string" ]]; then
echo "found $animal"
fi
done
Granted you'd need something a bit more to make sure you didn't find animals[horse-2] when searching for animals[horse]
(if you had that in your array)