In Bash, what is the simplest way to test if an array contains a certain value?
Edit: With help from the answers and the comments, after some testing, I came up with this:
function contains() {
local n=$#
local value=${!n}
for ((i=1;i < $#;i++)) {
if [ "${!i}" == "${value}" ]; then
echo "y"
return 0
fi
}
echo "n"
return 1
}
A=("one" "two" "three four")
if [ $(contains "${A[@]}" "one") == "y" ]; then
echo "contains one"
fi
if [ $(contains "${A[@]}" "three") == "y" ]; then
echo "contains three"
fi
I'm not sure if it's the best solution, but it seems to work.
A small addition to @ghostdog74's answer about using
case
logic to check that array contains particular value:Or with
extglob
option turned on, you can do it like this:Also we can do it with
if
statement:Expanding on the above answer from Sean DiSanti, I think the following is a simple and elegant solution that avoids having to loop over the array and won't give false positives due to partial matches
Which can be called like so:
Here is a small contribution :
Note: this way doesn't distinguish the case "two words" but this is not required in the question.
My version of the regular expressions technique that's been suggested already:
What's happening here is that you're expanding the entire array of supported values into words and prepending a specific string, "X-" in this case, to each of them, and doing the same to the requested value. If this one is indeed contained in the array, then the resulting string will at most match one of the resulting tokens, or none at all in the contrary. In the latter case the || operator triggers and you know you're dealing with an unsupported value. Prior to all of that the requested value is stripped of all leading and trailing whitespace through standard shell string manipulation.
It's clean and elegant, I believe, though I'm not too sure of how performant it may be if your array of supported values is particularly large.
If you prefer you can use equivalent long options:
I typically just use:
non zero value indicates a match was found.