鉴于
hasArgs=a:b:c:
x=b
if [[ ${hasArgs} = *$x:* ]] ; then …
我希望我可以用一个不太特定于 Bash 的替代方案来替换上面的双括号测试(意味着没有子 shell/命令等)
参数扩展没有帮助,因为它不消耗变量。
if [ "${hasArgs}" != "${hasArgs#$x:}" ] ; then …
是否有适合此用例的简单(一行)解决方案?
答案1
它不是一行代码,但它具有很强的可读性,并且可以扩展以检查任意数量的参数:
hasArgs="a:b:c"
x=b
case "$hasArgs" in
*$x*)
echo "$x is present"
;;
esac
答案2
以下内容将在 sh 中运行:
if echo "$hasArgs" | grep -q "$x"; then
答案3
实际上,您可以在这里使用标准参数扩展(您只是缺少通配符):
$ args=a:b:c:
$ x=b
$ echo "${args%$x:*}"
a:
$ if [ "$args" != "${args#*$x:}" ]; then echo 'b: is present'; fi
b: is present
(或同等"${args%$x:*}"
)
缺点是你需要在 后面加上冒号b
,所以a:b
或者普通的b
不会匹配,但它也会匹配a:bb:c
。 ([[ $var = *$x:* ]]
以及明显的模式匹配也case
有同样的缺点。)
匹配所有b
, b:c
, a:b
, a:b:c
, 而不匹配a:bb:c
会有点棘手。我能想到的就是这样的:
args=a:b:c
x=b
IFS=: # affects globally
set -f # affects globally...
for x in $args; do
if [ "$x" = "b" ]; then
echo "b is present"
fi
done
除非你想把所有的情况都写出来:
args=a:b:c
x=b
found=0
case "$args" in
$x) found=1;;
$x:*) found=1;;
*:$x) found=1;;
*:$x:*) found=1;;
esac
if [ "$found" = 1 ]; then ...; fi
使用正则表达式(在 Bash 中)更容易:
args=b:c
x=b
if [[ $args =~ (^|:)$x(:|$) ]]; then
echo "b found"
fi