我想测试字符串是否具有"子字符串"。在线大多数答案都是基于bash。我尝试了
if [ $string == "*substring*" ]
不起作用。当前
if echo ${string} | grep -q "substring"
工作。还有其他更好的方法吗?
使用POSIX符合参数 - 扩展和经典测试命令。
#!/bin/sh
substring=ab
string=abc
if [ "$string" != "${string%"$substring"*}" ]; then
echo "$substring present in $string"
fi
(或)明确使用test
操作员为
if test "$string" != "${string%$substring*}" ; then
在posix-features中,只有您将无法在条件enerm emen em ender pattern pattern pattern 模式>没有外部实用程序。
也就是说:
-
Kenster的有用答案显示了如何使用
case ... esac
语句的分支进行模式匹配。 -
inian的有用答案显示了如何在条件上使用 m匹配,使用模式作为参数扩展的一部分。
您自己的grep
方法肯定是一种选择,尽管您应该双重引用${string}
:
if echo "${string}" | grep -q "substring"; ...
一种更有效的方法是使用expr
实用程序,但请注意,POSIX它仅限于Bres( basic 正则表达式),这是有限的:
string='This text contains the word "substring".'
if expr "$string" : ".*substring" >/dev/null; then echo "matched"; fi
请注意,正则表达式 - 第三操作数 - 隐式锚定在输入的 start 上,因此需要.*
。
>/dev/null
抑制了 expr
的默认输出,这是在这种情况下匹配的字符串的长度。(如果没有任何匹配,则输出为0
,而退出代码设置为1
)。
如果您只是在测试substring(或使用文件名通配符匹配的任何内容),则可以使用case
:
#!/bin/sh
while read line; do
case "$line" in
*foo*) echo "$line" contains foo ;;
*bar*) echo "$line" contains bar ;;
*) echo "$line" isnt special ;;
esac
done
$ ./testit.sh
food
food contains foo
ironbar
ironbar contains bar
bazic
bazic isnt special
foobar
foobar contains foo
这是基本的Bourne Shell功能。它不需要任何外部程序,也不需要特定于bash的程序,也不需要Posix。因此它应该是非常便携的。
简短的答案是否定的,不是如果您尝试使用vanilla sh,而无需bash扩展。在许多现代系统上,/bin/sh
实际上是指向/bin/bash
的链接,该链接提供了sh
的功能(大部分)的超集。您的最初尝试将与Bash的内置[[
扩展测试命令:http://mywiki.wooledege.org/bashfaq/031