Bash Find Out IF a Variable Contains a Substring

How do I determine whether a variable called spath=”/srv/www/cyberciti.biz/https” contains a substring called “cyberciti.biz”? How can I check if a string contains a Substring in Bash scripting?

You can always find out if a string/word/variable contains another string/word in Linux or Unix shell scripting. For example find out if a word called tips exists in $var="Here are some tips for you". There are many ways to test if a string is a substring in bash. We can find if variable contains a substring in our shell scripts using awk, perl, bash, and other methods.
Tutorial requirements
Operating system/appLinux/Unix with bash
Root privileges required No
Difficulty Easy (rss)
Estimated completion time 2m
Table of contents

Find out if bash variable contains a substring

Let us see various bash methods to check if a string contains a substring.

Using case syntax

You can use the portable BourneShell syntax as follows:

case "$var" in
    *pattern1* ) echo "do something #1";;
    *pattern2* ) echo "do something # 2";;
    * ) echo "Error...";;
esac

Here is a sample code:

#!/bin/bash
spath="/srv/www/cyberciti.biz/https" 
sync_root(){
	echo "Running rsync..."
        rsync -ar $spath/* root@backup.cyberciti.biz:$spath
}
 
case "$spath" in
    *cyberciti.biz*) sync_root ;;
    *) echo "Error: Domain does not exits in path.";;	
esac

Bash check if a string contains a substring

The [ and [[ evaluate conditional expression. This is a synonym for the test command/builtin. However, [[ is bash’s improvement to the [ command. Please note that the following is bash specific syntax and it will not work with BourneShell:

[[ $var = *pattern1* ]]
## OR ##
if [[ $var = *pattern1* ]]
then
    echo "Do something"
fi

Here is a sample code:

#!/bin/bash
# Wrapper for faq pdf generator
# Manually generate pdf files and upload to static nixCraft download server
# --
# Get all defaults and functions 
[[ -f ~/backend/utils/functions.sh ]] && ~/backend/utils/functions.sh
_pdfwriter=${_PYTHON_PDF_WRITER:-~/backend/utils/pdfwriter.beta}
 
[[ $# -eq 0 ]] && { echo "Usage: $0 faq-url"; exit 1; }
 
[[ $1 != *cyberciti.biz/faq/* ]] && { printf "Error: Specify faq url (e.g., http://www.cyberciti.biz/faq/url-1-2-3/)\n"; exit 2; }
 
${_pdfwriter} faq "$1"

Using bash regex syntax

Bash v3 and above also supports additional regular expressions. The syntax is as follows to see if bash variable contains a substring:

[[ $var =~ .*substring.* ]]
[[ $value =~ .*container1.* ]] && do_something

For example find out if a word ‘faq’ exists in $url:

#!/bin/bash
url="https://www.cyberciti.biz/faq/bash-for-loop/"
[[ $url =~ .*faq* ]] && echo "Found" || echo "Not found"
## if syntax ##
if [[ $url =~ .*faq.* ]] 
then
   echo "I found a word faq in ${url}."
else
   echo "Sorry. Not found."
fi

Using AWK regex syntax

The syntax is pretty simple:

# define a var at shell
var="This is a test"
 
# use awk 
awk '$0~/test/{print "A substring called test found"}' <<< $var

The grep command syntax

In this example I am going to use the grep to check if a string contains a substring in Bash script:

var="Hello world"
grep -q 'foo' <<< $var && echo "A substring called foo found" || echo "Not a substring"
grep -q 'world' <<< $var && echo "A substring called world found" || echo "Not a substring"

Let us try out the if command in our tiny shell script:

#!/bin/bash
 
my_quote='Look for opportunities in every change in your life'
search_word='opportunities'
 
if grep -q "${search_word}" <<< "$my_quote"
then
  echo "I found '${search_word}' word in \$my_quote variable."
else
  echo "Sorry I cannot find '${search_word}' word in \$my_quote variable."
fi

For example here is my LXD backup script that ignore containers from backup defined in the $ignore:

#!/bin/bash
# Purpose - Basic shell script to backup required LXD containers under Linux
# Author - Vivek Gite {https://www.cyberciti.biz} under GPL version 2.0+ 
# --------------------------------------------------------------------------
## Get today's date ##
NOW=$(date +'%m-%d-%Y')
#
# NFS mounted backup or AWS efs 
#
DEST="/backups/lxd/${NOW}" 
#
# Define config and other paths 
#
LXD_CONF="${DEST}/$HOSTNAME-lxd.config.txt"
LXD_INST_LIST="${DEST}/$HOSTNAME-lxd.instances.list.txt"
LXD_VER="${DEST}/$HOSTNAME-lxd.version.txt"
#
# Containers to ignore from backup 
#
ignore="nginx-build-service docker-test-service mysqld-test-data php8-build-service www-testing"
 
[ ! -d "$DEST" ] && mkdir -p "$DEST"
 
## Dump LXD server config ##
lxd init --dump > "${LXD_CONF}"
 
## Dump all instances list ##
lxc list > "${LXD_INST_LIST}"
 
## Make sure we know LXD version too ##
snap list lxd > "${LXD_VER}"
 
## Backup all Instances
for i in $(lxc list -c n --format csv)
do
     file="$DEST/${i}-backup.tar.xz"	
     # Ignore backup for this container if defined in $ignore
     grep -q $i <<< $ignore && continue	
     lxc export "${i}" "$file" --optimized-storage --compression xz
done

Conclusion

Checking if a variable contains a substring is useful in bash scripting. Of course, we can can use Perl, Python and more too. See your local bash man page for more information:
man bash
man grep
man awk

🐧 If you liked this page, please support my work on Patreon or with a donation.
🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source/DevOps topics:
CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
10 comments… add one
  • yoander Mar 16, 2010 @ 13:58

    BASH Regular expression

    [[ $var =~ '.*cyberciti.biz.*' ]] && echo Yes || echo No

  • yoander Mar 16, 2010 @ 14:04

    BASH Regular expression

    [[ '/srv/www/cyberciti.biz/https' =~ '.*cyberciti.biz.*' ]] && echo Yes || No

  • yoander Mar 16, 2010 @ 14:06

    [[ '/srv/www/cyberciti.biz/https' =~ '.*cyberciti.biz.*' ]] && echo Yes || echo No

  • Santosh Nov 14, 2012 @ 14:05

    Thank you!

  • toto Feb 1, 2013 @ 22:08
    if [ "${haystack}" != "${haystack/${needle}/}" ]
    then
      echo "found needle in haystack"
    fi
  • taikedz Jun 16, 2017 @ 18:05

    Wow plenty commenting on the bash regex. Well I just wanted to chime in there too. This is sufficient:

        [[ "$MYVAR" =~ cyberciti.biz ]] && echo "Yes it does."

    It should be noted that the pattern should NOT be quoted, else it is treated as a literal (yoander’s examples are, alas, incorrect)

    I frequently do an arguments check at the start of my scripts to see if we should just print help and exit:

    5877159485fc7d89d6bfca_000010

    Edited by admin to correct syntax.

    • taikedz Jun 16, 2017 @ 18:06

      Of course, I forgot a ‘[‘ in my second example :-/

  • Nina Aug 2, 2020 @ 14:24

    How about?

    5877159485fc7d89d6bfca_000011

  • Sai Aug 2, 2020 @ 16:33

    I had no idea about such a good bash syntax.

  • Trey Blancher Aug 2, 2020 @ 19:11

    You need to pick a better font for displaying monospace text. The tildes (`~`) look way too similar to hyphens/dashes (`-`), I had to increase the font size and still I had difficulty verifying those were indeed tildes.

Leave a Reply

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

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.