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.