ケースパターンを否定する方法

ケースパターンを否定する方法

条件を追加するにはどうすればよいか、必要な条件が検出されない場合はコマンドが実行されます。

私のコード:

case $price in
[0-9] | "." | "$") echo "Numbers, . , $ Only"
            ;;
esac

数値「.」が検出されると、このコマンドが実行されます。そして「$」。これらの何も検出されない場合、どのような意味でそれを変更するかによってコマンドが実行されます。または、この機能を実行するために使用できるより良いコマンドはありますか?

答え1

基本ケースを追加:

case $price in
[0-9] | "." | "$") true
            ;;
*) 
   do-something
   ;;
esac

答え2

caseこの回答は、すでに説明した問題ではなく、一致の問題を意味します。

まず、有効な文字列がどのように見えるかを定義する必要があります。もちろん、最も単純な定義は1つの構造のみを受け入れます。

  1. 1つ以上の数字で始まります(前にゼロが許可されています)。
  2. 小数点
  3. 末尾の2桁の数字(必要な場合00
  4. ドル記号(前に空白なし)

正規表現(例grepを参照man 7 regex)として、次のように書かれます。

^[0-9]+\.[0-9][0-9]\$$
  • ^文字列の先頭を表示します。つまり、文字列の前には何も来ません。[0-9]+
  • \.ポイントはリテラルポイントとして扱われるようにエスケープされます。
  • ドル記号は\$文字通り受け入れられるようにエスケープされます。
  • 末尾は$文字列の終わりを示します。つまり、テキストの後には何も来ることはできません。$

テスト:

> echo '0123.45$' | grep -E '^[0-9]+\.[0-9][0-9]\$$'
0123.45$

ドットと末尾の数字を含むドル記号の両方がオプションになるように定義を変更すると、正規表現は次のように変更されます。

^[0-9]+(\.[0-9][0-9])?\$?$

テスト:

> echo '0123$' | grep -E '^[0-9]+\.[0-9][0-9]\$$'

# no match
> echo '0123$' | grep -E '^[0-9]+(\.[0-9][0-9])?\$?$'
0123$
> echo '0123.45$' | grep -E '^[0-9]+(\.[0-9][0-9])?\$?$'
0123.45$

シェルは正規表現を直接使用できますが、caseパターン内では使用できません。構造が必要です[[ ]]。ただし、文字列が一致するかどうかを知りたいので、次の理由はありませんcase

if [[ "$price" =~ ^[0-9]+(\.[0-9][0-9])?\$?$ ]]; then
  :
else
  :
fi

本当に必要な場合は、シェル bulitin を使用してcaseオプションを設定し、正規表現を「シェル正規表現」に書き換えることができます。extglobshopt

shopt -s extglob

^[0-9]+(\.[0-9][0-9])?\$?$それからそれはなる

+([0-9])?(.[0-9][0-9])?($)

先頭$

代わりに、必要に応じて最初から確認する$0123.45必要があります。0123.45$$

  • grep/ [[ ]]:^\$?[0-9]+(\.[0-9][0-9])?$
  • シェルパターンマッチング:?($)+([0-9])?(.[0-9][0-9])

確認しやすい

順序は重要ではなく、正しい文字のみを考慮している場合は、より単純な式を使用できます。

  • grep/ [[ ]]:^[0-9.$]+$
  • シェルパターンマッチング:+([0-9.$])

はい

#! /bin/bash

shopt -s extglob

for value in 1234 1234EUR; do
    case "$value" in
            +([0-9]))
                    echo "value OK: '${value}'"
            ;;
            *)
                    echo "value not OK: '${value}'"
            ;;
    esac
done

答え3

単一の正の整数のみを含む文字列をシェルステートメントと一致させるには、case次のようにします。

case "${string:--}" in
(*[!0-9]*)  
! echo 'Invalid value for $string!';;
(*[!0]*) 
echo "$string is a positive integer greater than 0.";;
(*)
echo "$string is 0.";;
esac

最初の一致では、含まれていない拡張値(単一文字を含む)をcaseフィルタリングします。設定されていないか空の場合、このパターンに展開されるため、まだこのパターンと一致します。リード反転リターン${string:--}0123456789$string-!echo(常に0)1に - したがって、無効な値が含まれている場合、case設定は1を返します。$string

$string次に、ゼロ以外の1桁の数字を含むすべての値と一致します。したがって、有効な値の前にあるゼロの数は正に$string一致します。

最後の項目は、最初の 2 つの項目と一致しないすべての項目と一致します。つまり、1つ以上のゼロのみが一致します。

関連情報