web-dev-qa-db-ja.com

caseステートメントでパターンを使用する方法は?

manページには、caseステートメントが「ファイル名拡張パターン一致」を使用することが記載されています。
私は通常、いくつかのパラメーターに短い名前を付けたいので、次のようにします。

case $1 in
    req|reqs|requirements) TASK="Functional Requirements";;
    met|meet|meetings) TASK="Meetings with the client";;
esac

logTimeSpentIn "$TASK"

req*me{e,}tなどのパターンを試してみましたが、これらはファイル名展開のコンテキストでこれらの値に一致するように正しく展開されると理解していますが、機能しません。

69
Ramiro Rela

ブレースの展開は機能しませんが、_*_、_?_、および_[]_は機能します。 _shopt -s extglob_を設定すると、 拡張パターンマッチング を使用することもできます。

  • ?()-パターンの0回または1回の出現
  • *()-パターンの0回以上の出現
  • +()-1つ以上のパターンの出現
  • @()-パターンの1回の出現
  • !()-パターン以外のすべて

以下に例を示します。

_shopt -s extglob
for arg in Apple be cd meet o mississippi
do
    # call functions based on arguments
    case "$arg" in
        a*             ) foo;;    # matches anything starting with "a"
        b?             ) bar;;    # matches any two-character string starting with "b"
        c[de]          ) baz;;    # matches "cd" or "ce"
        me?(e)t        ) qux;;    # matches "met" or "meet"
        @(a|e|i|o|u)   ) fuzz;;   # matches one vowel
        m+(iss)?(ippi) ) fizz;;   # matches "miss" or "mississippi" or others
        *              ) bazinga;; # catchall, matches anything not matched above
    esac
done
_
130

ブレースを使用できるとは思わない。

Conditional Constructs のケースに関するBashマニュアルによると。

patternには、チルダ展開、パラメータ展開、コマンド置換、および算術展開が行われます。

ブレース拡張 残念ながら何もありません。

したがって、次のようなことをする必要があります。

case $1 in
    req*)
        ...
        ;;
    met*|meet*)
        ...
        ;;
    *)
        # You should have a default one too.
esac
39
plundra

ifおよびgrep -Eq

arg='abc'
if echo "$arg" | grep -Eq 'a.c|d.*'; then
  echo 'first'
Elif echo "$arg" | grep -Eq 'a{2,3}'; then
  echo 'second'
fi

どこ:

  • -qgrepが出力を生成するのを防ぎ、単に終了ステータスを生成します
  • -Eは拡張正規表現を有効にします

私はこれが好きです:

  • pOSIX 7です
  • it 拡張正規表現をサポート 、POSIX caseとは異なり
  • ケースが少ない場合、構文はcaseステートメントよりも不格好です

1つの欠点は、外部caseプログラムを呼び出すため、grepよりも遅い可能性が高いことですが、Bashを使用するときはパフォーマンスを最後に考慮する傾向があります。

caseはPOSIX 7

https://stackoverflow.com/a/4555979/895245 で述べられているように、bashはshoptなしでデフォルトでPOSIXに準拠しているように見えます

引用は次のとおりです。 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_01 セクション「ケース条件付き構成」:

条件付きコンストラクトケースは、いくつかのパターンの最初のパターンに対応する複合リストを実行します(パターンマッチング表記を参照)[...]同じ複合リストを持つ複数のパターンは、「|」で区切られます。シンボル。 [...]

ケース構成の形式は次のとおりです。

case Word in
     [(] pattern1 ) compound-list ;;
     [[(] pattern[ | pattern] ... ) compound-list ;;] ...
     [[(] pattern[ | pattern] ... ) compound-list]
  esac

そして http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_1 セクション「2.13。パターンマッチング表記法」は?*および[]