1. Overview

When we have a list of elements in a variable, sometimes we want to check if a particular element exists in that list or not. Unfortunately, Bash doesn’t provide a built-in function to do it.

In this tutorial, we’ll see how to check whether a variable exists in a list or not. To do this, we’ll learn to iterate over the list using for, to use grep, and to use regular expressions with Bash’s [[ ]].

2. Problem Example

Let’s start with a list of fruits called list_of_fruits:

$ list_of_fruits="banana pear apple strawberry lime"

In this case, we are using whitespaces as items delimiters. However, we can choose any character as a delimiter. Now, we want to check if a variable exists in the list or not.

Let’s suppose there is a function called exists_in_list that checks if an element exists in a list or not. This function receives the list, the items delimiter, and an element as parameters. Additionally, this function should return 0 if the element exists in the list and return 1 otherwise.

In Bash, we return 0 when the execution was successful, in this case, when we find the item. Otherwise, we return any other non 0 value when the execution wasn’t successful, in this case, when we don’t find the item. These return values follow standard Bash exit codes making it easy to call the function exists_in_list inside an if‘s condition.

We’ll use the exists_in_list function calling it this way:

$ exists_in_list "$LIST" "$DELIMINTER" "$ELEMENT"

Then, let’s see how we would check the existence of the fruits “pear” and “raspberry” in the list list_of_fruits, and using whitespaces to delimit items:

$ if exists_in_list "$list_of_fruits" " " pear; then
    echo "pear is in the list"
else
    echo "pear is not in the list"
fi
$ if exists_in_list "$list_of_fruits" " " raspberry; then
    echo "raspberry is in the list"
else
    echo "raspberry is not in the list"
fi

In the following sections, we’ll define the function exists_in_list using different approaches.

3. Iterating Over the List

One method to check if the element exists in the list or not is to iterate over the list. We can use a for loop to iterate the list.

The for loop receives a variable and a list in the form of for VARIABLE in LIST. When we do this, for will iterate over the LIST and assign each element to VARIABLE. Let’s see how it works:

$ for x in element1 element2 element3; do
    echo $x
done
element1
element2
element3

We can see, the for loop iterated over the items, assigning each item to the variable x. The list items have to be delimited by whitespaces so for can separate them.

Now, we can check if an element exists inside the for loop, comparing each element to the desired value. Let’s iterate the list and print a message if we find the item “element2“:

$ {
    for x in element1 element2 element3; do
        if [ $x = "element2" ]; then
            echo "The element was found"
        fi
    done
}
The element was found

Our input list can use any string as a delimiter. So, we have to substitute the items delimiter with whitespaces. To do this, we can use the tr command. We’ll echo the list and pipe it through tr DELIMITER ” “, and assign the result to a new variable.

Finally, we can define the function exists_in_list. Let’s receive the list of elements as the first parameter, the delimiter as the second parameter, and the value to search for as the third parameter:

$ function exists_in_list() {
    LIST=$1
    DELIMITER=$2
    VALUE=$3
    LIST_WHITESPACES=`echo $LIST | tr "$DELIMITER" " "`
    for x in $LIST_WHITESPACES; do
        if [ "$x" = "$VALUE" ]; then
            return 0
        fi
    done
    return 1
}

We can see, we first convert the input list so we can use the variable LIST_WHITESPACES  in the for loop. Then, the function returns the value 0 if the item is found. Otherwise, the function returns the value 1.

Let’s run the example from the previous section:

$ if exists_in_list "$list_of_fruits" " " pear; then
    echo "pear is in the list"
else
    echo "pear is not in the list"
fi
pear is in the list
$ if exists_in_list "$list_of_fruits" " " raspberry; then
    echo "raspberry is in the list"
else
    echo "raspberry is not in the list"
fi
raspberry is not in the list

4. Using grep

We can also take advantage of grep‘s functionality to find a word within a list of words.

First, we’ll substitute the items delimiter with a newline character. Then, we can pipe the list delimited with newlines to grep -F -q -x “$VALUE”. This way, we check if VALUE is on the list or not.

Let’s review the grep‘s parameter we are using:

  • -F: this disables any regex feature, so grep searches for the literal string even if there are characters like * or +
  • -q: this enables the quiet mode, so grep doesn’t print any message
  • -x: this configures grep to find a match only of the whole line matches

To substitute the delimiter with a new line, we can use tr again. To do this, we can echo the list and pipe it through tr DELIMITER ‘\n’.

Now, let’s define the function exists_in_list using the grep approach:

$ function exists_in_list() {
    LIST=$1
    DELIMITER=$2
    VALUE=$3
    echo $LIST | tr "$DELIMITER" '\n' | grep -F -q -x "$VALUE"
}

In this case, we don’t need to use the return command. The exists_in_list function will return the same value as the last command executed, in this case, grep.

Let’s see how it works:

$ if exists_in_list "$list_of_fruits" " " pear; then
    echo "pear is in the list"
else
    echo "pear is not in the list"
fi
pear is in the list
$ if exists_in_list "$list_of_fruits" " " raspberry; then
    echo "raspberry is in the list"
else
    echo "raspberry is not in the list"
fi
raspberry is not in the list

By default, grep matches any occurrence, be it a whole word or part of it. However, we are using the -x parameter to match only the whole line.

Let’s test our function searching for “berry”, which is not in our list but is inside the “strawberry” item:

$ if exists_in_list "$list_of_fruits" " " berry; then
    echo "berry is in the list";
else
    echo "berry is not in the list";
fi
berry is not in the list

As we expected, “berry” wasn’t found in the list.

5. Using Regular Expressions with Bash’s [[ ]]

We have another alternative to check if a variable exists in the list or not. We can use regular expressions inside Bash’s [[ ]] to determine if the list contains an item or not.

First, let’s review what conditions we need to check if the list contains the item:

  • If the item is in the middle of the list, there is a delimiter before and after the item
  • When the list contains only the item, the list starts and ends with the item
  • If the item is the first item in the list, the list starts with the item, and there is a delimiter after the item
  • Finally, if the item is the last item in the list, the list ends with the item, and there is a delimiter before the item

Now, we can write a regular expression to cover all those cases:

($DELIMITER|^)$VALUE($DELIMITER|$)

We can use regular expressions in Bash using [[ STRING =~ REGEX ]]. This command returns the value 0 if the regular expression matches. Otherwise, it returns the value 1. As we need this behavior in the exist_in_list function, we can run the [[ ]] command without any explicit return command.

Let’s rewrite the function exists_in_list using this method:

$ function exists_in_list() {
    LIST=$1
    DELIMITER=$2
    VALUE=$3
    [[ "$LIST" =~ ($DELIMITER|^)$VALUE($DELIMITER|$) ]]
}

Let’s check if “pear” and “raspberry” exists in the list_of_fruits list:

$ if exists_in_list "$list_of_fruits" " " pear; then
    echo "pear is in the list"
else
    echo "pear is not in the list"
fi
pear is in the list
$ if exists_in_list "$list_of_fruits" " " raspberry; then
    echo "raspberry is in the list"
else
    echo "raspberry is not in the list"
fi
raspberry is not in the list

6. Conclusion

In this tutorial, we saw three methods to check if a variable exists in a list.

We first looked at using a simple for loop to iterate the list and verify if the item exists or not. Then, we piped the list separated with newlines through grep, and we used grep to check if a line matches the item. Finally, we learned to use regular expressions in Bash and use them to check if an item exists in the list.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.