How to check if a string contains a substring in Bash

后端 未结 26 1871
慢半拍i
慢半拍i 2020-11-22 01:58

I have a string in Bash:

string=\"My string\"

How can I test if it contains another string?

if [ $string ?? \'foo\' ]; then         


        
相关标签:
26条回答
  • 2020-11-22 02:11

    One is:

    [ $(expr $mystring : ".*${search}.*") -ne 0 ] && echo 'yes' ||  echo 'no'
    
    0 讨论(0)
  • 2020-11-22 02:12

    Extension of the question answered here How do you tell if a string contains another string in POSIX sh?:

    This solution works with special characters:

    # contains(string, substring)
    #
    # Returns 0 if the specified string contains the specified substring,
    # otherwise returns 1.
    contains() {
        string="$1"
        substring="$2"
    
        if echo "$string" | $(type -p ggrep grep | head -1) -F -- "$substring" >/dev/null; then
            return 0    # $substring is in $string
        else
            return 1    # $substring is not in $string
        fi
    }
    
    contains "abcd" "e" || echo "abcd does not contain e"
    contains "abcd" "ab" && echo "abcd contains ab"
    contains "abcd" "bc" && echo "abcd contains bc"
    contains "abcd" "cd" && echo "abcd contains cd"
    contains "abcd" "abcd" && echo "abcd contains abcd"
    contains "" "" && echo "empty string contains empty string"
    contains "a" "" && echo "a contains empty string"
    contains "" "a" || echo "empty string does not contain a"
    contains "abcd efgh" "cd ef" && echo "abcd efgh contains cd ef"
    contains "abcd efgh" " " && echo "abcd efgh contains a space"
    
    contains "abcd [efg] hij" "[efg]" && echo "abcd [efg] hij contains [efg]"
    contains "abcd [efg] hij" "[effg]" || echo "abcd [efg] hij does not contain [effg]"
    
    contains "abcd *efg* hij" "*efg*" && echo "abcd *efg* hij contains *efg*"
    contains "abcd *efg* hij" "d *efg* h" && echo "abcd *efg* hij contains d *efg* h"
    contains "abcd *efg* hij" "*effg*" || echo "abcd *efg* hij does not contain *effg*"
    
    0 讨论(0)
  • 2020-11-22 02:14

    You can use Marcus's answer (* wildcards) outside a case statement, too, if you use double brackets:

    string='My long string'
    if [[ $string == *"My long"* ]]; then
      echo "It's there!"
    fi
    

    Note that spaces in the needle string need to be placed between double quotes, and the * wildcards should be outside. Also note that a simple comparison operator is used (i.e. ==), not the regex operator =~.

    0 讨论(0)
  • 2020-11-22 02:14

    As Paul mentioned in his performance comparison:

    if echo "abcdefg" | grep -q "bcdef"; then
        echo "String contains is true."
    else
        echo "String contains is not true."
    fi
    

    This is POSIX compliant like the 'case "$string" in' the answer provided by Marcus, but it is slightly easier to read than the case statement answer. Also note that this will be much much slower than using a case statement. As Paul pointed out, don't use it in a loop.

    0 讨论(0)
  • 2020-11-22 02:14

    Exact word match:

    string='My long string'
    exactSearch='long'
    
    if grep -E -q "\b${exactSearch}\b" <<<${string} >/dev/null 2>&1
      then
        echo "It's there"
      fi
    
    0 讨论(0)
  • 2020-11-22 02:15

    I use this function (one dependency not included but obvious). It passes the tests shown below. If the function returns a value > 0 then the string was found. You could just as easily return 1 or 0 instead.

    function str_instr {
       # Return position of ```str``` within ```string```.
       # >>> str_instr "str" "string"
       # str: String to search for.
       # string: String to search.
       typeset str string x
       # Behavior here is not the same in bash vs ksh unless we escape special characters.
       str="$(str_escape_special_characters "${1}")"
       string="${2}"
       x="${string%%$str*}"
       if [[ "${x}" != "${string}" ]]; then
          echo "${#x} + 1" | bc -l
       else
          echo 0
       fi
    }
    
    function test_str_instr {
       str_instr "(" "'foo@host (dev,web)'" | assert_eq 11
       str_instr ")" "'foo@host (dev,web)'" | assert_eq 19
       str_instr "[" "'foo@host [dev,web]'" | assert_eq 11
       str_instr "]" "'foo@host [dev,web]'" | assert_eq 19
       str_instr "a" "abc" | assert_eq 1
       str_instr "z" "abc" | assert_eq 0
       str_instr "Eggs" "Green Eggs And Ham" | assert_eq 7
       str_instr "a" "" | assert_eq 0
       str_instr "" "" | assert_eq 0
       str_instr " " "Green Eggs" | assert_eq 6
       str_instr " " " Green "  | assert_eq 1
    }
    
    0 讨论(0)
提交回复
热议问题