私の目標は、(case
+ esac
でのみ)で番号の範囲を確認し、その範囲を出力することです。だから例えば:
>=0<=80
を出力します>=81<=100
を出力します以下の私のスクリプトの問題は、0〜9の数値の場合にのみ>=0<=90
のみを印刷します。スクリプトを修正して、数値の範囲に従って正しい出力を印刷する方法を教えてください。
#!/bin/ksh
read number
case $number in
[0-80]) echo ">=0<=80";;
[81-100]) echo ">=81<=100";;
[101-120]) echo ">=101<=120";;
[121-300]) echo ">=121<=300";;
esac
case
はパターンマッチング専用であり、算術評価を行いません(zsh
の<x-y>
拡張パターンマッチング演算子を検討する場合を除いて)。 [...]
は、指定されたセットに基づいてone文字(または一部の実装では照合要素)に一致するだけです。したがって、たとえば、[0-80]
は、0
から8
または0
(つまり、0、1、2、3、4、5、6、7、8のいずれか)であれば、-one文字に一致します。
次のようなパターンで数字を照合できます。
case $(($number)) in
([0-9]|[1-7][0-9]|80) echo ">=0<=80";;
(8[1-9]|9[0-9]|100) echo ">=81<=100";;
... and so on
esac
しかし、それが適切なツールではないことが簡単にわかります。
[...]
は、one文字を指定された文字のリストと照合します。したがって、[121-300]
は、1、2、1〜3、0または0の任意の文字と照合されます。したがって、 [0-3]
または[0123]
。
使用する:
if [ "$number" -ge 0 ] && [ "$number" -le 80 ]; then
echo ">=0<=80"
Elif [ "$number" -ge 81 ] && [ "$number" -le 100 ]; then
echo ">=81<=100"
Elif ... and so on
...
fi
case
を使用する別の方法は次のようになります。
case $((
(number >= 0 && number <= 80) * 1 +
(number > 80 && number <= 100) * 2 +
(number > 100 && number <= 120) * 3 +
(number > 120 && number <= 300) * 4)) in
(1) echo ">=0<=80";;
(2) echo ">=81<=100";;
(3) echo ">=101<=120";;
(4) echo ">=121<=300";;
(0) echo "None of the above";;
esac
または、三項演算子(x ? y : z
)を使用します。
case $((
number >= 0 && number <= 80 ? 1 :
number > 80 && number <= 100 ? 2 :
number > 100 && number <= 120 ? 3 :
number > 120 && number <= 300 ? 4 : 0)) in...
または、@ mikeservのように、ボックスの外側で考えます case
ロジックを逆にして、1
をこれらの算術比較の値と照合します 。
実際、これはとても簡単です。 case
についての重要な点は、パターンとの最初の一致を見つけるために必要なだけ拡張されることです。それは仕様の振る舞いです。そして、あなたはそれを既知の文字列で設定し、パターンの展開を評価することができます。
case 1:${number:--} in
(1:*[!0-9]*|1:0*[89]*)
! echo NAN
;;
($((number<81))*)
echo "$number >=0<=80"
;;
($((number<101))*)
echo "$number >=81<=100"
;;
($((number<121))*)
echo "$number >=101<=120"
;;
($((number<301))*)
echo "$number >=121<=300"
;;
esac
case
は、パターンの先頭の1を見つけるために必要以上にこれらのパターンを展開することはありません。これは、ユーザー入力を操作する場合に特に重要です。これは、実際にそれを入れている同じcaseステートメントで算術展開コンテキストに入れようとする前に、$number
の内容を安全に検証できることを意味します数学の拡張。
これはあまりいい方法ではありませんが、これを使用できます。
#!/bin/ksh
read number
case $number in
[0-9]|[1-7][0-9]|80) echo echo ">=0<=80";;
8[1-9]|9[0-9]|100) echo ">=81<=100";;
10[1-9]|11[0-9]|120) echo ">=101<=120";;
12[1-9]|130) echo ">=121<=300";;
esac