web-dev-qa-db-ja.com

文字列がPOSIXシェルの正規表現に一致するかどうかをテストする方法は? (bashではない)

私はbashではなくUbuntuシステムシェルを使用していますが、通常の方法では機能しないことがわかりました。

#!/bin/sh
string='My string';

if [[ $string =~ .*My.* ]]
then
   echo "It's there!"
fi

エラーはみつかりません!

この問題を解決するにはどうすればよいですか?

19
harryz

[[ ... ]]はbash-ismです。 grepを通常のifと一緒に使用するだけで、テストをシェルに依存しないようにすることができます。

if echo "$string" | grep -q "My"; then
    echo "It's there!"
fi
18

なぜそのような単純なパターンにgrepを使用するのですか? Sh組み込みマッチングエンジンによる不要なforkを回避します。

case "$value" in
  *XXX*)  echo OK ;;
  *) echo fail ;;
esac

POSIXに準拠しています。 Bashには 簡略化された構文 があります:

if [[ "$value" == *XXX* ]]; then :; fi
18
gavenkoa

exprを使用できます:

if expr "$string" : "My" 1>/dev/null; then
  echo "It's there";
fi

これはshbashの両方で機能します。

便利な機能として:

exprq() {
  local value

  test "$2" = ":" && value="$3" || value="$2"
  expr "$1" : "$value" 1>/dev/null
}

# Or `exprq "somebody" "body"` if you'd rather ditch the ':'
if exprq "somebody" : "body"; then 
  echo "once told me"
fi

man exprからの引用:

   STRING : REGEXP
          anchored pattern match of REGEXP in STRING
5
devnull
[ "${string#*My}" != "$string" ] && echo "It's there!"

${...}

${...}構文は変数の展開を実行します。これの多くの形式は移植可能です(便利な${foo#bar}${foo##bar}${foo%bar}、および${foo%%bar}を含みますが、そうでないものもあります。

${!...}は間接変数展開を実行します。これはバシズムです。代わりにevalを使用してください。

${parameter/pattern/string}は、バシズムであるパターン置換を実行します。これを修正するための提案については、次のセクションを参照してください。

${parameter:offset:length}は、バシズムである部分文字列展開を実行します。これを修正するための提案については、以下を参照してください。

配列変数は移植できません。適切なセパレーターにいくらか注意を払えば、通常、パフォーマンスに大きな影響を与えることなく、一連の${foo#bar}展開などで置き換えることができます。

0
Wanlong Gao