How to Tell If a Bash String Contains a Substring on Linux

Linux laptop with a bash prompt
fatmawati ahmad 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’ll show you some simple, reliable techniques.

Why is this 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 to allow your script to decide what to do next. It can look for a label or device name in a configuration file or a command string in a user’s input line.

Linux users are blessed with a variety of text editing utilities. Some are built into the Bash shell, others are provided as standalone utilities or applications. There’s a reason Unix-derived operating systems are replete with string manipulation facilities.

Some things that appear to be files are not just files. They are special files Represent things like hardware devices and sources of system information. The abstraction performed by the operating system gives them the look and properties 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.

Text is also used as input and output for commands in a terminal window. This allows for the redirection and forwarding of inputs and outputs. This functionality supports the ability to chain sequences of Linux commands together and pass the output of one command as input to the next.

Regardless of its origin, searching the received text for a meaningful word, command, label, or other indicator is a standard part of dealing with text-based data. Here’s a collection of simple techniques that you can incorporate into your own scripts.

Finding substrings with bash buildins

The double brackets “[[...]]” String comparison test can be used if Instructions to determine if a string contains another string.

Copy this script into an editor and save it in 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 need to make the script executable with the chmod Command. This is a step that is always required to make a script executable. You must do this every time you create a script file. Replace each with the name of the appropriate script.

chmod +x double.sh

Make the 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, including no characters. If the substring “key” is within the target string, with or without leading or trailing characters, the test returns true.

In our example, characters precede the substring. These are matched by the first asterisk. There are no letters after the substring, but since an asterisk matches no characters either, the test still passes.

For flexibility, we can change 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 this goes.

./double2.sh

Running the double2.sh script

This works the same way, with the benefit that we can use variable names instead of literal strings. Converting our small solution into a function offers 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 ours check_substring Function with a mixture of variables and literal strings. We used shopt With -s (set) Option to set nocasematchto ignore case for matches.

That’s how it works.

./double3.sh

Running the double3.sh script

We can use the trick of enclosing the substring in asterisks 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

Use case statements instead of very long if -Instructions can make scripts easier to read and debug. When you needed to check whether a string contained one of many possible substrings, the case Statement would be the best choice.

./case.sh

Running the case.sh script

The substring is found.

Find substrings with grep

Aside from the built-in bash-ins, the first text search tool you’re likely to reach for is grep. we can use grepThe innate ability of to search for a string within a string to look for 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 used echo to send the string grep, which searches for the substring. We use the -q (silent) option to stop grep write something to the standard output.

If the result of the commands in the brackets “(...)” is equal to zero, it means a match was found. Because zero equals true in bash, the if statement is fulfilled and the then clause is executed.

Let’s see what his output is.

./subgrep.sh

Running the subgrep.sh script

Finding substrings with sed

we can use sed to also find a substring.

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 in sed with a here redirect, <<<. This is used to redirect values ​​into a command in the current shell. It doesn’t invoke a subshell like a pipe would.

The first -n is the exam. It will return true if the output from the sed Command is non-zero. Only then can the output look like this sed may be non-zero if a matching row was found. If that’s the case, $substring must have been found $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 script’s logic by manipulating the value of $substring for the comparison to fail.

./subsed.sh

Running the subsed.sh script with a mismatched substring

Stop looking, found it

Other tools can find substrings, such as awk and Perl but a simple use case like finding a substring doesn’t justify their added functionality nor the added complexity. In particular, using the bash built-ins to search for substrings is fast, easy, and requires no external tools.

TIED TOGETHER: How to use case statements in bash scripts

Leave a Reply

Your email address will not be published. Required fields are marked *