如何检查字符串是否在Bash中包含子字符串

我在Bash中有一个字符串: shell

string="My string"

如何测试它是否包含另外一个字符串? c#

if [ $string ?? 'foo' ]; then
  echo "It's there!"
fi

哪里?? 是我未知的运算符。 我是否使用echo和grepbash

if echo "$string" | grep 'foo'; then
  echo "It's there!"
fi

看起来有点笨拙。 ide


#1楼

我发现常常须要此功能,所以我在.bashrc使用了一个自制的shell函数,以下所示,它使我能够根据须要.bashrc重复使用它,并具备易于记忆的名称: 函数

function stringinstring()
{
    case "$2" in 
       *"$1"*)
          return 0
       ;;
    esac   
    return 1
}

要测试$string2 (例如123abcABC )中是否包含$string1 (例如abc ),我只须要运行stringinstring stringinstring "$string1" "$string2"并检查返回值,例如 post

stringinstring "$str1" "$str2"  &&  echo YES  ||  echo NO

#2楼

这也适用: 测试

if printf -- '%s' "$haystack" | egrep -q -- "$needle"
then
  printf "Found needle in haystack"
fi

负面测试是: spa

if ! printf -- '%s' "$haystack" | egrep -q -- "$needle"
then
  echo "Did not find needle in haystack"
fi

我认为这种样式更经典-较少依赖Bash shell的功能。 线程

--参数是纯POSIX偏执狂,用于防止相似于选项的输入字符串,例如--abc-acode

注意:在一个紧凑的循环此代码会比使用内部击壳特征慢得多 ,由于一个(或两个)独立的过程将被建立并经由配管链接。


#3楼

这个堆栈溢出的答案是惟一一个捕获空格和破折号的答案

# For null cmd arguments checking   
to_check=' -t'
space_n_dash_chars=' -'
[[ $to_check == *"$space_n_dash_chars"* ]] && echo found

#4楼

正如该SO线程主要介绍bash同样 ,我在此帖子的底部发布了一个大小写无关的 bash函数。

反正有个人

兼容答案

因为已经有不少使用Bash特定功能的答案,所以有一种在功能较差的shell下工做的方法,例如busybox

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

实际上,这可使:

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

这是在bashdashkshash (busybox)下进行测试的,结果始终是:

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

融入一项功能

正如@EeroAaltonen要求的,这是相同演示的版本,在相同的shell下进行了测试:

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
}

而后:

$ 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'.

注意:您必须转义或双引号和/或双引号:

$ 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'.

功能简单

这是在busybox破折号bash下测试的:

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

那是全部人!

那么如今:

$ 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

...或者若是提交的字符串可能为空,如@Sjlver所指出,则该函数将变为:

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

或如AdrianGünter的评论所建议,避免使用-o switche:

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

最终(简单)功能:

并进行反向测试以使它们更快地运行:

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

使用空字符串:

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

不区分大小写(仅限bash !)

对于不区分大小写的测试字符串,只需将每一个字符串转换为小写便可:

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

校验:

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

#5楼

我不肯定要使用if语句,可是用case语句能够获得相似的效果:

case "$string" in 
  *foo*)
    # Do stuff
    ;;
esac