我在Bash中有一个字符串: shell
string="My string"
如何测试它是否包含另外一个字符串? c#
if [ $string ?? 'foo' ]; then echo "It's there!" fi
哪里??
是我未知的运算符。 我是否使用echo和grep
? bash
if echo "$string" | grep 'foo'; then echo "It's there!" fi
看起来有点笨拙。 ide
我发现常常须要此功能,所以我在.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
这也适用: 测试
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
或-a
。 code
注意:在一个紧凑的循环此代码会比使用内部击壳特征慢得多 ,由于一个(或两个)独立的过程将被建立并经由配管链接。
# For null cmd arguments checking to_check=' -t' space_n_dash_chars=' -' [[ $to_check == *"$space_n_dash_chars"* ]] && echo found
正如该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
这是在bash , dash , ksh和ash (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'.
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
对于不区分大小写的测试字符串,只需将每一个字符串转换为小写便可:
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
我不肯定要使用if语句,可是用case语句能够获得相似的效果:
case "$string" in *foo*) # Do stuff ;; esac