我在Bash中有一个字符串:
string="My string"
如何测试它是否包含另一个字符串?
if [ $string ?? 'foo' ]; then
echo "It's there!"
fi
哪里是我不认识的接线员。我使用echo和grep吗?
if echo "$string" | grep 'foo'; then
echo "It's there!"
fi
这看起来有点笨拙。
我在Bash中有一个字符串:
string="My string"
如何测试它是否包含另一个字符串?
if [ $string ?? 'foo' ]; then
echo "It's there!"
fi
哪里是我不认识的接线员。我使用echo和grep吗?
if echo "$string" | grep 'foo'; then
echo "It's there!"
fi
这看起来有点笨拙。
当前回答
我喜欢sed。
substr="foo"
nonsub="$(echo "$string" | sed "s/$substr//")"
hassub=0 ; [ "$string" != "$nonsub" ] && hassub=1
编辑,逻辑:
使用sed从字符串中删除子字符串的实例如果新字符串与旧字符串不同,则存在子字符串
其他回答
字符串包含变量(兼容或不区分大小写)
由于这些Stack Overflow的答案主要讲述了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、KornShell(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所问,这里是相同演示的一个版本,在相同的外壳下测试:
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、Dash和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" ]; }
或者正如Adrian Günter的评论所建议的,避免使用-o开关:
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
我不确定是否使用if语句,但您可以使用case语句获得类似的效果:
case "$string" in
*foo*)
# Do stuff
;;
esac
Bash 4+示例。注意:当单词包含空格等时,不使用引号会导致问题。请始终在Bash、IMO中引用。
以下是一些Bash 4+示例:
示例1,检查字符串中的“yes”(不区分大小写):
if [[ "${str,,}" == *"yes"* ]] ;then
示例2,检查字符串中的“yes”(不区分大小写):
if [[ "$(echo "$str" | tr '[:upper:]' '[:lower:]')" == *"yes"* ]] ;then
示例3,检查字符串中的“yes”(区分大小写):
if [[ "${str}" == *"yes"* ]] ;then
示例4,检查字符串中的“yes”(区分大小写):
if [[ "${str}" =~ "yes" ]] ;then
示例5,完全匹配(区分大小写):
if [[ "${str}" == "yes" ]] ;then
示例6,完全匹配(不区分大小写):
if [[ "${str,,}" == "yes" ]] ;then
示例7,完全匹配:
if [ "$a" = "$b" ] ;then
示例8,通配符match.ext(不区分大小写):
if echo "$a" | egrep -iq "\.(mp[3-4]|txt|css|jpg|png)" ; then
示例9,对区分大小写的字符串使用grep:
if echo "SomeString" | grep -q "String"; then
示例10,对不区分大小写的字符串使用grep:
if echo "SomeString" | grep -iq "string"; then
示例11,对字符串使用grep,不区分大小写,带通配符:
if echo "SomeString" | grep -iq "Some.*ing"; then
示例12,使用doublehash进行比较(如果变量为空会导致假阳性等)(区分大小写):
if [[ ! ${str##*$substr*} ]] ;then #found
享受
精确的单词匹配:
string='My long string'
exactSearch='long'
if grep -E -q "\b${exactSearch}\b" <<<${string} >/dev/null 2>&1
then
echo "It's there"
fi
正如Paul在绩效比较中提到的:
if echo "abcdefg" | grep -q "bcdef"; then
echo "String contains is true."
else
echo "String contains is not true."
fi
这是符合POSIX的,就像Marcus提供的答案中的“case“$string”一样,但它比case语句答案更容易阅读。还要注意,这将比使用case语句慢得多。正如保罗所指出的,不要在循环中使用它。