Checking Substrings/Prefixes
case or the [[ ]] test with glob wildcards.In this page:
Checking if a String Contains a Substring
[[ $str == *substring* ]] uses glob wildcards to check whether substring appears anywhere inside $str, since the unquoted * on each side matches any surrounding text (including none). This is the standard idiom for a simple contains check without needing grep.
Example: Checking if a String Contains a Substring
#!/bin/bash
sentence="The quick brown fox jumps"
if [[ $sentence == *brown* ]]; then
echo "Found 'brown' in the sentence"
fi
Login to try C/C++/Java/PHP code in the editor
Checking a Prefix or Suffix
[[ $str == prefix* ]] checks that $str starts with prefix, and [[ $str == *suffix ]] checks that it ends with suffix, by placing the wildcard only on the side you don't care about. This reads naturally and avoids manual substring slicing just to compare the start or end.
Example: Checking a Prefix or Suffix
#!/bin/bash
filename="report_2024.csv"
if [[ $filename == report_* ]]; then
echo "Starts with 'report_'"
fi
if [[ $filename == *.csv ]]; then
echo "Ends with '.csv'"
fi
Login to try C/C++/Java/PHP code in the editor
Using case for Substring Checks
case can perform the same kind of glob-based substring, prefix, and suffix checks as [[ ]], which is especially readable when you're distinguishing between several different possible patterns at once. Each pattern branch is tried in order until one matches.
Example: Using case for Substring Checks
#!/bin/bash
url="https://example.com/page"
case $url in
https://*)
echo "Secure URL"
;;
http://*)
echo "Insecure URL"
;;
*)
echo "Unknown URL scheme"
;;
esac
Login to try C/C++/Java/PHP code in the editor
Quoted Patterns Disable Glob Matching
If the pattern on the right of == inside [[ ]] is quoted, Bash treats it as a literal string rather than a glob pattern, so wildcards like * lose their special meaning and become ordinary characters to match exactly. This distinction is important to remember since it flips the check from contains to 'is exactly equal to'.
Example: Quoted Patterns Disable Glob Matching
#!/bin/bash
value="hello"
if [[ $value == h* ]]; then
echo "Unquoted pattern: glob match, starts with 'h'"
fi
if [[ $value == "h*" ]]; then
echo "This won't print"
else
echo "Quoted pattern: treated as literal 'h*', no match"
fi
Login to try C/C++/Java/PHP code in the editor
- Trying to use
[[ $str == *substring* ]]with the pattern in quotes; quoting the pattern turns off glob matching entirely and forces a literal, exact-string comparison instead. - Assuming
caseand[[ == ]]support regex-style anchors like^/$; they use glob wildcards (*,?,[...]), where*already implicitly means 'anything, including nothing, anywhere in that position'. - Using
[[ $str = *sub* ]](single=) and being surprised it also does glob matching; inside[[ ]], both=and==behave identically for pattern matching, unlike inside[ ]where=is strictly a literal string comparison.
[[ $str == *substring* ]]checks ifsubstringappears anywhere within$str, using unquoted glob wildcards.[[ $str == prefix* ]]checks if$strstarts withprefix;[[ $str == *suffix ]]checks if it ends withsuffix.casecan achieve the same checks with pattern branches, which reads well when checking several possible substrings at once.- Quoting the pattern (e.g.
"*substring*") disables glob matching and forces a literal, exact-string comparison -- the opposite of what you usually want here.
Chapter Quiz — Complete all 10 topics to unlock
0/10 topics done
Complete these topics first: