Linux では $STRING1 != "${STRING1/substr/"

Linux では $STRING1 != "${STRING1/substr/"

文字列が 1 つあり、それにサブ文字列が含まれているかどうかを確認したいです。そのため、このコマンドを使用しています。以下は Linux シェル スクリプトです。if ステートメントにある条件がどのように機能するかを知りたいだけです。

STRING1='This string contains substring.'
if [[ $STRING1 != "${STRING1/substr/}" ]]; then
  echo "Substring is present"
fi

答え1

これは、標準を記述するための複雑で ksh 固有の方法です (ただし、現在は他のいくつかのシェルでもサポートされています)。

case $STRING1 in
   *substr*) echo Substring is present
esac

または ksh 固有:

if [[ $STRING1 = *substr* ]]; then
  echo Substring is present
fi

${var/pattern/replacement}$varは、 の最初の出現がpatternに置き換えられた値に展開される ksh パラメータ展開演算子ですreplacement

最初に出現する も何も置き換え${STRING1/substr/}られず、削除されます。$STRING1substr

[[ string = pattern ]]および は、[[ string != pattern ]]文字列をパターンと照合する別の ksh 固有の構成要素です。パターンが引用符で囲まれている場合は、文字どおりに解釈されます。[[ string = "string" ]]等価演算子も同様です ( の場合は不等価です!=)。

したがって、と[[ $STRING1 != "${STRING1/substr/}" ]]の展開が異なる文字列を生成する場合、コマンドは true を返します。これは、内にが少なくとも 1 回出現した場合にのみ発生するため、 が含まれているかどうかを確認する方法です。$STRING1${STRING!/substr/}substr$STRING1$STRING1substr

[[...]]もも${var/pattern/replacement}標準sh構文ではありませんが、[コマンドと${var#pattern}演算子 (後者も ksh から来ています) は標準です。そのため、次のようなコードを目にすることがあります。

if [ "$STRING1" != "${STRING1#*substr*}" ]; then
  echo Substring is present
fi

これは、変数に部分文字列が含まれているかどうかを確認する標準的な方法ですが (Bourne ではありませんが)、やはり複雑であり、明らかなcaseステートメント アプローチに比べて利点はありません。

答え2

部分文字列が含まれているかどうかを確認する

実行が簡単そう

[ -z "${s##*substr*}" ] && echo Substring is present

が存在する場合、展開の結果は${…}null (長さ 0) になります。substr


...if文の条件はどのように機能しますか?

if [[ $STRING1 != "${STRING1/substr/}" ]]; then

substr2 つの文字列、つまり元の変更されていない文字列と、削除された同じ文字列 ( ) を比較します/substr/}。これらが異なる場合 ( !=)、元の文字列には が含まれていましたsubstr

関連情報