How to Tell If a Bash String Contains a Substring on Linux
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
Let’s run the script.
./double.sh
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
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 nocasematch
to ignore case for matches.
That’s how it works.
./double3.sh
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
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 grep
The 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
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
We can test the script’s logic by manipulating the value of $substring
for the comparison to fail.
./subsed.sh
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