Bash: Check if String Contains Substring

By 

Updated on

4 min read

Checking if a string contains a substring in Bash

Checking whether a string contains a substring is one of the most common operations in Bash scripting.

This guide covers four ways to do it: wildcard matching, the case statement, the regex operator, and grep.

Quick Reference

MethodExamplePortable
Wildcard [[ ]][[ "$STR" == *"$SUB"* ]]Bash only
case wildcardcase "$STR" in *"$SUB"*) ...Yes (POSIX sh)
Regex =~[[ "$STR" =~ .*"$SUB".* ]]Bash only
grep here-stringgrep -q "$SUB" <<< "$STR"Bash only
Does not contain[[ "$STR" != *"$SUB"* ]]Bash only
Case-insensitivegrep -qi "$SUB" <<< "$STR"Bash only

Using Wildcards

The simplest approach is to wrap the substring in asterisk wildcards (*) and use [[ ]] with the equality operator. An asterisk matches zero or more characters, so *"$SUB"* matches any string that contains $SUB.

In the following example, the script checks whether STR contains the substring SUB:

sh
#!/bin/bash

STR='GNU/Linux is an operating system'
SUB='Linux'

if [[ "$STR" == *"$SUB"* ]]; then
  echo "It is there."
fi
output
It is there.

This is the most readable and recommended approach for Bash scripts. Note that [[ ]] is Bash-specific and not available in POSIX sh. For more details on Bash test expressions, see Bash comparison operators .

Using the case Statement

The case statement also supports wildcard patterns, making it a clean option for substring checks:

sh
#!/bin/bash

STR='GNU/Linux is an operating system'
SUB='Linux'

case "$STR" in
  *"$SUB"*)
    echo "It is there."
    ;;
esac
output
It is there.

The case approach works in both Bash and POSIX sh, making it more portable than [[ ]].

Using the Regex Operator

The =~ operator inside [[ ]] tests a string against a regular expression. The right-hand side is treated as a regex pattern, and .* matches zero or more of any character:

sh
#!/bin/bash

STR='GNU/Linux is an operating system'
SUB='Linux'

if [[ "$STR" =~ .*"$SUB".* ]]; then
  echo "It is there."
fi
output
It is there.

While this works, it is more complex than the wildcard approach for simple substring checks. Use =~ when you need full regular expression matching; for example, to match a pattern like a date or IP address format.

Using grep

The grep command can search for a substring within a string using a here-string (<<<):

sh
#!/bin/bash

STR='GNU/Linux is an operating system'
SUB='Linux'

if grep -q "$SUB" <<< "$STR"; then
  echo "It is there."
fi
output
It is there.

The -q option suppresses output and returns an exit code of 0 if the pattern is found. This approach runs an external grep process and is usually slower than the pure-Bash methods above. Use it when you need grep features such as case-insensitive search (-i) or fixed-string matching (-F).

FAQ

Which method should I use?
For most Bash scripts, use the wildcard method: [[ "$STR" == *"$SUB"* ]]. It is the most readable and requires no subshell. Use case when you need POSIX portability. Use =~ only when you need regular expression matching.

How do I check if a string does NOT contain a substring?
Flip the operator in the wildcard method: [[ "$STR" != *"$SUB"* ]]. With grep, negate the exit status: if ! grep -q "$SUB" <<< "$STR".

How do I do a case-insensitive substring check?
Use grep -qi "$SUB" <<< "$STR". With [[ ]], convert both strings to lowercase first using parameter expansion: [[ "${STR,,}" == *"${SUB,,}"* ]].

Does the wildcard method work with special characters in the substring?
Yes, as long as $SUB is quoted: *"$SUB"*. Quoting prevents the variable content from being interpreted as a glob pattern.

Are these methods Bash-specific?
The [[ ]] and =~ methods are Bash-specific. The case wildcard method is POSIX-compliant and works in any POSIX shell. grep with <<< requires Bash for the here-string syntax, but grep itself is available on all systems.

Conclusion

The simplest and most readable way to check if a string contains a substring in Bash is wildcard matching inside [[ ]]. For POSIX portability, use the case statement. For regular expression matching, use =~. For pattern-based searches with grep options, use grep -q with a here-string.

For more on working with strings in Bash, see the guides on comparing strings and if/else statements .

Tags

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page