How to tell if a Bash string contains a substring on Linux

Linux laptop showing a bash prompt
fatmawati achmad zaenuri/Shutterstock.com

Sometimes in Linux scripts you want to know if a text string contains a specific smaller string. There are many ways to do this. We show you some simple and reliable techniques.

Why is it useful?

Searching a string for a smaller substring is a common requirement. An example would be reading text from a file or human input and searching the string for a specific substring so that your script can decide what to do next. It could be looking for a tag or device name in a configuration file or a command string on a user input line.

Linux users are blessed with a plethora of utilities for manipulating text. Some are built into the Bash shell, others are provided as stand-alone utilities or applications. There is a reason why Unix-derived operating systems have abundant string manipulation capabilities.

Some things that appear to be files are not simple files. They are special files representing things like hardware devices and system information sources. The abstraction performed by the operating system gives them the appearance and characteristics of files. You can read information from them, as text of course, and in some cases write to them, but they are not ordinary files.

The text is also used as input and output for commands in a terminal window. This allows input and output redirection and pipelining. That functionality supports the ability to chain Linux scripts, passing the output of one command as input to the next.

Regardless of its origins, searching the text we receive for a meaningful word, command, tag, or some other indicator is a standard part of handling text-based data. Here is a collection of simple techniques that you can include in your own scripts.

Find substrings with Bash Builtins

The double brackets”[[...]]The string comparison test can be used in if instructions to determine if a string contains another string.

Copy this script into an editor and save it to a file called “double.sh”.

#!/bin/bash

if [[ "monkey" = *"key"* ]]; then
  echo "key is in monkey"
else
  echo "key is not in monkey"
fi

You will need to make the script executable with the chmod domain. This is a step that is always required to make any script executable. You will need to do this each time you create a script file. Substitute the appropriate script name in each case.

chmod +x double.sh

make a script executable with chmod

Let’s run the script.

./double.sh

Running the double.sh script

This works because the asterisk” * ” represents any sequence of characters, even without characters. If the “key” of the substring is found within the target string, with or without leading or trailing characters, the test will return true.

In our example, there are characters in front of the substring. These correspond to the first asterisk. There are no letters after the substring, but since an asterisk also does not match any characters, the test still passes.

For more flexibility, we can modify our script to handle variables instead of literal strings. This is the “double2.sh” script.

#!/bin/bash

string="Monkey"
substring="key"

if [[ $string = *$substring* ]]; then
  echo "$substring was found in $string"
else
  echo "$substring was not found in $string"
fi

Let’s see how that works.

./double2.sh

Running the double2.sh script

This works the same way, with the advantage that we can use variable names instead of literal strings. Turning our small solution into a function will provide the most flexibility.

This is the “double3.sh” script.

#!/bin/bash

shopt -s nocasematch

string="Monkey"
substring="Key"
capital="London"

check_substring ()
{
if [[ $1 = *$2* ]]; then
  echo "$2 was found in $1"
else
  echo "$2 was not found in $1"
fi
}

check_substring "Monkey" "key" 
check_substring $string $substring
check_substring $string "banana"
check_substring "Wales" $capital

we call our check_substring function using a combination of variables and literal strings. We use shopt with his -s (set) option to configure nocasematchso that the matches are not case sensitive.

Is that how it works.

./double3.sh

Running the double3.sh script

We can use the trick of wrapping the substring in asterisks in case statements, too. This is “case.sh”.

#!/bin/bash

shopt -s nocasematch

string="Wallaby"
substring="Wall"

case $string in

  *$substring*)
    echo "$substring was found in $string"
    ;;

  *)
    echo "Nothing matched: $string"
    ;;
esac

Wearing case statements instead of very long if Declarations can make scripts easier to read and debug. If I needed to check if a string contained one of many possible substrings, the case statement would be the best option.

./case.sh

Running the case.sh script

The substring is found.

Find substrings with grep

Beyond Bash’s built-in features, the first text search tool you’re likely to come across is grep. we can use grepThe innate ability to search a string within a string to find our substrings.

This script is called “subgrep.sh”.

#!/bin/bash

string="porridge pot"
substring="ridge"

if $(echo $string | grep -q $substring); then
  echo "$substring was found in $string"
else
  echo "$substring was not found in $string"
fi

The script uses echo to send the string to grep, which searches for the substring. we are using the -q option (silent) to stop grep writing anything to standard output.

If the result of the commands in parentheses “(...)” equals zero, it means a match was found. because zero equals true in bash, the if the statement is met and then the clause is executed.

Let’s see what your output is.

./subgrep.sh

Running the subgrep.sh script

Find substrings with sed

we can use sed to find a substring, too.

By default, sed prints all text that is fed into it. Using sed -n prevents this. The only lines that are printed are matching lines. This expression will print any lines that match or contain the value of $substring.

"/$substring/p"

We feed the value of $string within sed using a redirect here, <<<. This is used to redirect values ​​to a command in the current shell. It doesn’t invoke a sublayer like a pipeline would.

First -n is the proof. return true if the output of sed command is nonzero. The only way the output of sed can be nonzero if a matching line was found. If that’s the case, $substring must have been found in $string.

This is “subsed.sh”.

#!/bin/bash

string="Sweden"
substring="eden"

if [ -n "$(sed -n "/$substring/p" <<< $string)" ]; then
  echo "$substring was found in $string"
else
  echo "$substring was not found in $string"
fi

We get the expected response when we run the script.

./subsed.sh

Running the subsed.sh script

We can test the logic of the script by editing the value of $substring for the comparison to fail.

./subscribed.sh

Run subsed.sh script with mismatched substring

stop looking i found it

Other tools can find substrings, like awk Y Perl but a simple use case like finding a substring doesn’t guarantee its additional functionality or added complexity. In particular, using Bash’s built-in functions to search for substrings is fast, simple, and requires no external tools.

RELATED: How to use case statements in Bash scripts

Leave a Comment