Check if Array Contains a Value in Bash

Here are a few ways you can check if an array contains a specific value in bash scripts.
Warp Terminal

I have had so many instances where I wanted to check if a value was present in an array or not. You can probably iterate over all the array items and check it individually, but what if I give you the red pill?

I have created an array in which there is a string asdf and I want to make sure if I really put it in the array or not. Following is how to check for the string asdf in an array:

if [[ "${array[@]}" =~ 'asdf' ]]; then
    echo "the string 'asdf' is in the array"
fi
🚧
The above code will also match 00asdf00. For more accurate matching, continue reading.

The easiest method for checking if a value is present in a given that is to first expand the array such that all the elements are displayed, and then simply "grep" for it.

There are two ways you can "grep for it". Let's look at both of these methods.

🚧
This guide is specific to Bash users, it will not work with POSIX shells like Dash.

Method 1: Use regex to check array value

By far, this is the easiest approach (at least in my opinion):

#!/usr/bin/env bash

array=('10' '00' '101')

if [[ "${array[@]}" =~ '101' ]]; then
    echo "Found the number 5"
fi

In case you do not know, the @ operator in Bash, when substituted with a real index, just expands the entire array and "prints the whole array" (sort of). Then, a weird operator is used... The =~ operator.

This operator does not have a "formal name" in the official Bash document, but I like to call it the "regex operator". Since it is used for pattern matching.

With the help of the regex operator, I search for a specific pattern. Since each element (when "expanded" with the @ operator) is separated by spaces (it's bad, I know), we can easily search for a particular "word" that matches with an individual element.

This is how the current method of searching for a value in a Bash array works.

To prove that, below is the output one gets from running this script:

Found the number 5

Method 2: Use grep to see if array contains value

If it is too hard for you to remember what the regex operator is (I can understand, it was hard for me to remember in the beginning too), we can resort to some ugly hacks! :D

#!/usr/bin/env bash

array=('10' '00' '101')

if echo "${array[@]}" | grep '101' > /dev/null; then
    echo "Found the number 5"
fi

What we are doing here is pretty much what the =~ operator did for us in the previous method. But here, we are doing something that one might do if they were on a command line.

We are literally printing every element of the array and checking for the existance of a pattern using the grep utility.

We also put a handy little redirect to /dev/null. This is beacause, if a match is found, the entire matching line will be printed to the STDOUT. You probably don't want that.

πŸ’‘
Most command line utilities exit with their return code as 0 when they exit successfully.

In our case, the return code of grep, if it found a match, will be 0. Otherwise it will be any other, non-zero number. This way, we can take advantage of a utility's exit code and use that as a condition in our if-statement.

For the above script, following is the expected output:

Found the number 5

More precised matching

As you might have notied in the warning at the top of this article, the above stated methods not only match the entire word for a pattern, but they can also match with a subset of a string. And then give a "pseudo success indication" that the value you are looking for is present, but in reality, it is not.

Let's take a look at what I am trying to warn you against.

#/usr/bin/env bash

array=('hello' 'world' 'randomwords1000101sandwhich')

if [[ "${array[@]}" =~ '1000101' ]]; then
    echo "The number we were looking for, is present"
fi

And, let's run this to see what output this produces.

The number we were looking for, is present

Ouch! Yes, the value we are looking for is definitely present in the array, but that is not the "entire value". It matched a subset of an entire element! This is a side-effect. Let's deal with this effectively.

Method 3: Use loops to check array value (for exact match)

Time to run around in circles err, I mean loops!

#!/usr/bin/env bash

array=('hello' 'world' 'randomwords1000101sandwhich')
matched=false

for element in "${array[@]}"; do
    if [[ "$element" == '1000101' ]]; then
        matched=true;
    fi
done

if [[ "$matched" == 'false' ]]; then
    echo "The number you are looking for, is absent from the array... :("
else
    echo "The number you are looking for, is present in the array; hoo_rray_"
fi

Here, instead of using any regex operator or the grep tool itself, I do an exact match for every element of an array. I also use a "flag" variable (matched) to check if the match actually occured or not.

πŸ’‘
I can embed the if-condition in the loop itself, but that would only be useful to check if a value is present, not if a value is absent. That is why I use the flag variable.

I do this first, by looping over every element of the array. Then, by using the == operator to check if the exact string is present or not. If present, I set the value of our flag variable (matched) as true, since we did find a match :)

Finally, I have a simple if condition which prints the result.

I get the following output:

The number you are looking for, is absent from the array... :(

Conclusion

In this article, I go over three methods that you can use to check for a value in a Bash array.

The first two methods are to expand the entire array and perform a regular expression match, which can be error-prone, if not done correctly.

The final method is to iterate over all elements and check for an exact match. This last method is for when you need to find an exact match, for confirmation.

I presonally perfer the regex match, but I also use the exact match method when I see the Bat-Signal! (Yes, I'm Batman!)

About the author
Pratham Patel

Pratham Patel

You will find me tinkering with software until my system crashes. And then I keep on writing about my findings.

Become a Better Linux User

With the FOSS Weekly Newsletter, you learn useful Linux tips, discover applications, explore new distros and stay updated with the latest from Linux world

It's FOSS

Great! You’ve successfully signed up.

Welcome back! You've successfully signed in.

You've successfully subscribed to It's FOSS.

Success! Check your email for magic link to sign-in.

Success! Your billing info has been updated.

Your billing was not updated.