In Bash, what is the simplest way to test if an array contains a certain value?
After having answered, I read another answer that I particularly liked, but it was flawed and downvoted. I got inspired and here are two new approaches I see viable.
array=("word" "two words") # let's look for "two words"
grep
and printf
:(printf '%s\n' "${array[@]}" | grep -x -q "two words") && <run_your_if_found_command_here>
for
:(for e in "${array[@]}"; do [[ "$e" == "two words" ]] && exit 0; done; exit 1) && <run_your_if_found_command_here>
For not_found results add || <run_your_if_notfound_command_here>
a=(b c d)
if printf '%s\0' "${a[@]}" | grep -Fqxz c
then
echo 'array “a” contains value “c”'
fi
If you prefer you can use equivalent long options:
--fixed-strings --quiet --line-regexp --null-data
This is working for me:
# traditional system call return values-- used in an `if`, this will be true when returning 0. Very Odd.
contains () {
# odd syntax here for passing array parameters: http://stackoverflow.com/questions/8082947/how-to-pass-an-array-to-a-bash-function
local list=$1[@]
local elem=$2
# echo "list" ${!list}
# echo "elem" $elem
for i in "${!list}"
do
# echo "Checking to see if" "$i" "is the same as" "${elem}"
if [ "$i" == "${elem}" ] ; then
# echo "$i" "was the same as" "${elem}"
return 0
fi
done
# echo "Could not find element"
return 1
}
Example call:
arr=("abc" "xyz" "123")
if contains arr "abcx"; then
echo "Yes"
else
echo "No"
fi
given :
array=("something to search for" "a string" "test2000")
elem="a string"
then a simple check of :
if c=$'\x1E' && p="${c}${elem} ${c}" && [[ ! "${array[@]/#/${c}} ${c}" =~ $p ]]; then
echo "$elem exists in array"
fi
where
c is element separator
p is regex pattern
(The reason for assigning p separately, rather than using the expression directly inside [[ ]] is to maintain compatibility for bash 4)
$ myarray=(one two three)
$ case "${myarray[@]}" in *"two"*) echo "found" ;; esac
found
I typically just use:
inarray=$(echo ${haystack[@]} | grep -o "needle" | wc -w)
non zero value indicates a match was found.