Bash: Check if String Contains Substring

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
| Method | Example | Portable |
|---|---|---|
Wildcard [[ ]] | [[ "$STR" == *"$SUB"* ]] | Bash only |
case wildcard | case "$STR" in *"$SUB"*) ... | Yes (POSIX sh) |
Regex =~ | [[ "$STR" =~ .*"$SUB".* ]] | Bash only |
grep here-string | grep -q "$SUB" <<< "$STR" | Bash only |
| Does not contain | [[ "$STR" != *"$SUB"* ]] | Bash only |
| Case-insensitive | grep -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:
#!/bin/bash
STR='GNU/Linux is an operating system'
SUB='Linux'
if [[ "$STR" == *"$SUB"* ]]; then
echo "It is there."
fiIt 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:
#!/bin/bash
STR='GNU/Linux is an operating system'
SUB='Linux'
case "$STR" in
*"$SUB"*)
echo "It is there."
;;
esacIt 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:
#!/bin/bash
STR='GNU/Linux is an operating system'
SUB='Linux'
if [[ "$STR" =~ .*"$SUB".* ]]; then
echo "It is there."
fiIt 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
(<<<):
#!/bin/bash
STR='GNU/Linux is an operating system'
SUB='Linux'
if grep -q "$SUB" <<< "$STR"; then
echo "It is there."
fiIt 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 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