我在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
这看起来有点笨拙。
当前回答
这也适用于:
if printf -- '%s' "$haystack" | egrep -q -- "$needle"
then
printf "Found needle in haystack"
fi
阴性试验为:
if ! printf -- '%s' "$haystack" | egrep -q -- "$needle"
then
echo "Did not find needle in haystack"
fi
我认为这种风格更为经典——更少依赖于Bash shell的特性。
--参数是纯粹的POSIX偏执狂,用于防止类似于选项的输入字符串,例如--abc或-a。
注意:在紧密循环中,此代码将比使用内部Bashshell特性慢得多,因为将创建一个(或两个)单独的进程并通过管道连接。
其他回答
试试oobash。
它是Bash 4的OO风格字符串库。它支持德语元音变音。它是用巴什语写的。
有许多函数可用:-base64Decode、-base64Encode、-acapital、-center、-charAt、concat、-concontains、-count、-endsWith、-equals、-equalsIgnoreCase、-reverse、-hashCode、-indexOf、-isAlnum、-isAlpha、-isAscii、-isDigit、-isEmpty、-isHexDigit、-isLowerCase、-isSpace、-isPrintable、-isUpperCase、-isVisible、-lastIndexOf、-length、-matches、-replaceAll、-replaceFirst、-startsWith,-substring、-swapCase、-toLowerCase、-toString、-toUpperCase、-trim和-zfill。
查看包含的示例:
[Desktop]$ String a testXccc
[Desktop]$ a.contains tX
true
[Desktop]$ a.contains XtX
false
oobash可在Sourceforge.net上获得。
我使用这个函数(一个不包括但很明显的依赖项)。它通过了以下测试。如果函数返回值>0,则找到字符串。你也可以很容易地返回1或0。
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
}
由于POSIX/BusyBox问题在没有提供正确答案(IMHO)的情况下结束,我将在这里发布答案。
最简单的答案是:
[ ${_string_##*$_substring_*} ] || echo Substring found!
or
[ "${_string_##*$_substring_*}" ] || echo 'Substring found!'
注意,对于某些shell(ash),双哈希是必须的。当未找到子字符串时,上面将计算[stringvalue]。它不会返回错误。找到子字符串时,结果为空,其结果为[]。这将抛出错误代码1,因为字符串被完全替换(由于*)。
最短最常见的语法:
[ -z "${_string_##*$_substring_*}" ] && echo 'Substring found!'
or
[ -n "${_string_##*$_substring_*}" ] || echo 'Substring found!'
另一个:
[ "${_string_##$_substring_}" != "$_string_" ] && echo 'Substring found!'
or
[ "${_string_##$_substring_}" = "$_string_" ] || echo 'Substring found!'
注意单个等号!
如果您喜欢正则表达式方法:
string='My string';
if [[ $string =~ "My" ]]; then
echo "It's there!"
fi
这里回答的问题的扩展如何判断POSIX sh中的字符串是否包含另一个字符串?:
此解决方案适用于特殊字符:
# 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*"