Check if a Bash array contains a value

arrays, bash

Solution

This approach has the advantage of not needing to loop over all the elements (at least not explicitly). But since `array_to_string_internal()` in array.c still loops over array elements and concatenates them into a string, it's probably not more efficient than the looping solutions proposed, but it's more readable.

if [[ " ${array[*]} " =~ [[:space:]]${value}[[:space:]] ]]; then
    # whatever you want to do when array contains value
fi

if [[ ! " ${array[*]} " =~ [[:space:]]${value}[[:space:]] ]]; then
    # whatever you want to do when array doesn't contain value
fi

Note that in cases where the value you are searching for is one of the words in an array element with spaces, it will give false positives. For example,

array=("Jack Brown")
value="Jack"

The regex will see "Jack" as being in the array even though it isn't. So, you'll have to change `IFS` and the separator characters on your regex if you want still to use this solution, like this.

IFS="|"
array=("Jack Brown${IFS}Jack Smith")
value="Jack"

if [[ "${IFS}${array[*]}${IFS}" =~ "${IFS}${value}${IFS}" ]]; then
    echo "true"
else
    echo "false"
fi

unset IFS # or set back to original IFS if previously set

This will print "false".

Obviously, this can also be used as a test statement, allowing it to be expressed as a one-liner.

[[ " ${array[*]} " =~ " ${value} " ]] && echo "true" || echo "false"

Since this solution relies on regular expressions to check the array, you must escape any regex characters in the needle. For example, if you were searching with this.

array=("valueToBeFound")
value=".*"

You would have to set `value` to `\.\*`, otherwise all array elements will be seen to match.

Problem

In Bash, what is the simplest way to test if an array contains a certain value?

Original source

Related problems