How to check if a string contains a substring in Bash

后端 未结 26 1869
慢半拍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:28

    If you prefer the regex approach:

    string='My string';
    
    if [[ $string =~ "My" ]]; then
       echo "It's there!"
    fi
    
    0 讨论(0)
  • 2020-11-22 02:29

    stringContain variants (compatible or case independent)

    As these Stack Overflow answers tell mostly about Bash, I've posted a case independent Bash function at the very bottom of this post...

    Anyway, there is my

    Compatible answer

    As there are already a lot of answers using Bash-specific features, there is a way working under poorer-featured shells, like BusyBox:

    [ -z "${string##*$reqsubstr*}" ]
    

    In practice, this could give:

    string='echo "My string"'
    for reqsubstr in 'o "M' 'alt' 'str';do
      if [ -z "${string##*$reqsubstr*}" ] ;then
          echo "String '$string' contain substring: '$reqsubstr'."
        else
          echo "String '$string' don't contain substring: '$reqsubstr'."
        fi
      done
    

    This was tested under Bash, Dash, KornShell (ksh) and ash (BusyBox), and the result is always:

    String 'echo "My string"' contain substring: 'o "M'.
    String 'echo "My string"' don't contain substring: 'alt'.
    String 'echo "My string"' contain substring: 'str'.
    

    Into one function

    As asked by @EeroAaltonen here is a version of the same demo, tested under the same shells:

    myfunc() {
        reqsubstr="$1"
        shift
        string="$@"
        if [ -z "${string##*$reqsubstr*}" ] ;then
            echo "String '$string' contain substring: '$reqsubstr'.";
          else
            echo "String '$string' don't contain substring: '$reqsubstr'."
        fi
    }
    

    Then:

    $ myfunc 'o "M' 'echo "My String"'
    String 'echo "My String"' contain substring 'o "M'.
    
    $ myfunc 'alt' 'echo "My String"'
    String 'echo "My String"' don't contain substring 'alt'.
    

    Notice: you have to escape or double enclose quotes and/or double quotes:

    $ myfunc 'o "M' echo "My String"
    String 'echo My String' don't contain substring: 'o "M'.
    
    $ myfunc 'o "M' echo \"My String\"
    String 'echo "My String"' contain substring: 'o "M'.
    

    Simple function

    This was tested under BusyBox, Dash, and, of course Bash:

    stringContain() { [ -z "${2##*$1*}" ]; }
    

    Then now:

    $ if stringContain 'o "M3' 'echo "My String"';then echo yes;else echo no;fi
    no
    $ if stringContain 'o "M' 'echo "My String"';then echo yes;else echo no;fi
    yes
    

    ... Or if the submitted string could be empty, as pointed out by @Sjlver, the function would become:

    stringContain() { [ -z "${2##*$1*}" ] && [ -z "$1" -o -n "$2" ]; }
    

    or as suggested by Adrian Günter's comment, avoiding -o switches:

    stringContain() { [ -z "${2##*$1*}" ] && { [ -z "$1" ] || [ -n "$2" ];};}
    

    Final (simple) function:

    And inverting the tests to make them potentially quicker:

    stringContain() { [ -z "$1" ] || { [ -z "${2##*$1*}" ] && [ -n "$2" ];};}
    

    With empty strings:

    $ if stringContain '' ''; then echo yes; else echo no; fi
    yes
    $ if stringContain 'o "M' ''; then echo yes; else echo no; fi
    no
    

    Case independent (Bash only!)

    For testing strings without care of case, simply convert each string to lower case:

    stringContain() {
        local _lc=${2,,}
        [ -z "$1" ] || { [ -z "${_lc##*${1,,}*}" ] && [ -n "$2" ] ;} ;}
    

    Check:

    stringContain 'o "M3' 'echo "my string"' && echo yes || echo no
    no
    stringContain 'o "My' 'echo "my string"' && echo yes || echo no
    yes
    if stringContain '' ''; then echo yes; else echo no; fi
    yes
    if stringContain 'o "M' ''; then echo yes; else echo no; fi
    no
    
    0 讨论(0)
提交回复
热议问题