Size: 748
Comment: converted to 1.6 markup
|
← Revision 17 as of 2025-04-11 03:27:15 ⇥
Size: 2376
Comment: Total rewrite. Are you happy, 81? I included your stupid == operator.
|
Deletions are marked like this. | Additions are marked like this. |
Line 3: | Line 3: |
There are many choices here: you can perform an exact substring match, or a [[glob]]-style pattern match, or a RegularExpression match. To match exact substrings, POSIX sh uses `case`: {{{ # POSIX case $bigvar in *substr*) ... ;; }}} If the substring is in a variable, and if an exact substring match is wanted, then the substring variable should be quoted: {{{ # POSIX case $bigvar in *"$substr"*) ... ;; }}} In Bash, you may also use the `[[` command. It follows the same quoting semantics as `case`: {{{ # Bash if [[ $bigvar = *substr* ]]; then ... # These are if [[ $bigvar == *substr* ]]; then ... # equivalent. if [[ $bigvar = *"$substr"* ]]; then ... # These are if [[ $bigvar == *"$substr"* ]]; then ... # equivalent. }}} In both `case` and `[[` you may also do glob-style pattern matching. Simply use unquoted glob characters in the pattern. If the pattern is in a variable, '''omit''' the double quotes, and it will be interpreted as a pattern instead of an exact substring. {{{ # POSIX case $filename in *.txt) ... ;; pattern='*.txt' case $filename in $pattern) ... ;; }}} |
|
Line 5: | Line 41: |
if [[ $foo = *bar* ]] | # Bash if [[ $filename = *.txt ]]; then ... if [[ $filename == *.txt ]]; then ... pattern='*.txt' if [[ $filename = $pattern ]]; then ... if [[ $filename == $pattern ]]; then ... |
Line 8: | Line 50: |
The above works in virtually all versions of Bash. Bash version 3 also allows regular expressions: |
In Bash 3.x or later, `[[` can also do Extended Regular Expression (ERE) matches using the `=~` operator: |
Line 11: | Line 52: |
if [[ $foo =~ ab*c ]] # bash 3, matches abbbbcde, or ac, etc. | # Bash # Matches ac, zabcz, xabbbbcq, etc. re='ab*c' if [[ $foo =~ $re ]]; then ... |
Line 14: | Line 58: |
If you are programming in the BourneShell instead of Bash, there is a more portable (but less pretty) syntax: | Storing the regular expression in a variable and using `=~ $variable` is strongly recommended, as it avoids many undesirable surprises. |
Line 16: | Line 60: |
POSIX sh has no builtin regular expression matching, but you can call external programs such as `expr` or `grep` to do it. | |
Line 17: | Line 62: |
case "$foo" in *bar*) .... ;; esac |
# POSIX # With expr, leading anchors are implied. # An initial .* works around this. if expr "$foo" : ".*$re" > /dev/null; then ... # With grep, anchoring must be requested if desired. if printf %s "$foo" | grep -q -- "$re"; then ... |
Line 22: | Line 71: |
{{{case}}} allows you to match variables against [[globbing]]-style patterns. If you need a portable way to match variables against [[RegularExpression|regular expressions]], use {{{grep}}} or {{{egrep}}}. | `expr` uses Basic Regular Expressions (BRE); `grep` defaults to BRE, but may use ERE with the `-E` option. |
Line 24: | Line 73: |
{{{ if echo "$foo" | grep bar >/dev/null; then ... }}} |
For more hints on string manipulations in Bash, see [[BashFAQ/100|FAQ #100]]. ---- CategoryShell |
How do I determine whether a variable contains a substring?
There are many choices here: you can perform an exact substring match, or a glob-style pattern match, or a RegularExpression match.
To match exact substrings, POSIX sh uses case:
# POSIX case $bigvar in *substr*) ... ;;
If the substring is in a variable, and if an exact substring match is wanted, then the substring variable should be quoted:
# POSIX case $bigvar in *"$substr"*) ... ;;
In Bash, you may also use the [[ command. It follows the same quoting semantics as case:
# Bash if [[ $bigvar = *substr* ]]; then ... # These are if [[ $bigvar == *substr* ]]; then ... # equivalent. if [[ $bigvar = *"$substr"* ]]; then ... # These are if [[ $bigvar == *"$substr"* ]]; then ... # equivalent.
In both case and [[ you may also do glob-style pattern matching. Simply use unquoted glob characters in the pattern. If the pattern is in a variable, omit the double quotes, and it will be interpreted as a pattern instead of an exact substring.
# POSIX case $filename in *.txt) ... ;; pattern='*.txt' case $filename in $pattern) ... ;;
# Bash if [[ $filename = *.txt ]]; then ... if [[ $filename == *.txt ]]; then ... pattern='*.txt' if [[ $filename = $pattern ]]; then ... if [[ $filename == $pattern ]]; then ...
In Bash 3.x or later, [[ can also do Extended Regular Expression (ERE) matches using the =~ operator:
# Bash # Matches ac, zabcz, xabbbbcq, etc. re='ab*c' if [[ $foo =~ $re ]]; then ...
Storing the regular expression in a variable and using =~ $variable is strongly recommended, as it avoids many undesirable surprises.
POSIX sh has no builtin regular expression matching, but you can call external programs such as expr or grep to do it.
# POSIX # With expr, leading anchors are implied. # An initial .* works around this. if expr "$foo" : ".*$re" > /dev/null; then ... # With grep, anchoring must be requested if desired. if printf %s "$foo" | grep -q -- "$re"; then ...
expr uses Basic Regular Expressions (BRE); grep defaults to BRE, but may use ERE with the -E option.
For more hints on string manipulations in Bash, see FAQ #100.