デュアルブラケットのグローバルマッチングに対するBashの代替

デュアルブラケットのグローバルマッチングに対するBashの代替

一方

hasArgs=a:b:c:
x=b
if [[ ${hasArgs} = *$x:* ]] ; then …

上記の二重括弧テストをBashにあまり特殊化されていない代替(サブシェル/コマンドなどがないことを意味する)に置き換えることができることを願っています。

パラメータ拡張は変数を消費しないため役に立ちません。

if [ "${hasArgs}" != "${hasArgs#$x:}" ] ; then …

このユースケースに適した単純な(1行)ソリューションはありますか?

答え1

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:bba:bb:c[[ $var = *$x:* ]]case

一致せずb、、、、をすべて一致させるのはややトリッキーですb:ca:b私が考えることができるのはこれだけです。a:b:ca: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

関連情報