Stphane Asked: 2018-08-04 14:26:19 +0800 CST2018-08-04 14:26:19 +0800 CST 2018-08-04 14:26:19 +0800 CST Bash 双括号全局匹配的替代方案 772 给定 hasArgs=a:b:c: x=b if [[ ${hasArgs} = *$x:* ]] ; then … 我希望我可以用较少的 Bash 特定替代方案替换上述双括号测试(意味着没有子外壳/命令等) 参数扩展没有帮助,因为它不扩展变量。 if [ "${hasArgs}" != "${hasArgs#$x:}" ] ; then … 是否有适合此用例的简单(单行)解决方案? bash test 3 个回答 Voted DopeGhoti 2018-08-04T14:30:57+08:002018-08-04T14:30:57+08:00 它不是单行的,但它非常易读,并且可以扩展以检查任意数量的参数: hasArgs="a:b:c" x=b case "$hasArgs" in *$x*) echo "$x is present" ;; esac jesse_b 2018-08-04T14:30:18+08:002018-08-04T14:30:18+08:00 以下将在 sh 中起作用: if echo "$hasArgs" | grep -q "$x"; then Best Answer ilkkachu 2018-08-04T15:26:55+08:002018-08-04T15:26:55+08:00 实际上,您可以在此处使用标准参数扩展(您只是缺少通配符): $ 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
它不是单行的,但它非常易读,并且可以扩展以检查任意数量的参数:
以下将在 sh 中起作用:
实际上,您可以在此处使用标准参数扩展(您只是缺少通配符):
(或同等
"${args%$x:*}"
)缺点是你需要在 之后有冒号
b
,a:b
否则一个普通的b
不会匹配,它也会匹配a:bb:c
。([[ $var = *$x:* ]]
以及明显的模式匹配case
具有相同的缺点。)匹配所有
b
,b:c
,a:b
,a:b:c
, 而不匹配a:bb:c
会有点棘手。我能想到的都是这样的:除非您想写出所有案例:
使用正则表达式(在 Bash 中)更容易: