
シェルスクリプトへの引数が10進表記法で整数(例えば、負ではない整数:0、1、2、3、…、17、…、42、…などですが、3.1416または-5ではない)であることを確認したいと思います。 (したがって、0x11または0x2Aとは異なります)。正規表現を条件としてCaseステートメントを作成する方法(数値一致)?私はいくつかの異なるアプローチを試しました(例:[0-9]+
または^[0-9][0-9]*$
)。そのどれも機能しません。次の例に示すように、有効な数字はその数字をキャプチャしてワイルドカードと一致するように設計された数値正規表現を介して渡されます *
。
i=1
let arg_n=$#+1
while (( $i < $arg_n )); do
case ${!i} in
[0-9]+)
n=${!i}
;;
*)
echo 'Invalid argument!'
;;
esac
let i=$i+1
done
出力:
$ ./cmd.sh 64
Invalid argument!
答え1
答え2
グレンが言ったように、"はcase
正規表現を使用せず、次のように使用します。模様「。大きな打撃(1)説明する、
case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac
ㅏ
case
コマンドが最初に展開されます。word
、それぞれの項目と一致しようとします。pattern
順番に、パス名拡張と同じ一致規則が使用されます(参照:パス名拡張次のような)。
同様に、POSIX仕様説明する、
…各模様...拡張と比較する必要があります。言葉, で説明されている規則に従ってパターンマッチング表記 …
だから模様ls -l -- *.sh
inまたはなどのパス名拡張パターン(別名ワイルドカード、別名ワイルドカード)rm -- *.bak
。
もちろん、shopt -s extglob
スライス[[ … =~ … ]]
したパンの後で最もきれいですが、POSIXではなく、元のツールの使い方を知っておくと便利です。たとえば、長年にわたり、プログラマは文字列が数字であるかどうかを調べて、数字かどうかを確認しました。いいえ数字。数字を(完全に)1つ以上の数字で構成される文字列として定義しました。したがって、文字列が空である場合、または数値以外の文字を含む場合、文字列は数値ではありません。case
次の文を使用してこれらの条件をテストできます。
case "$1" in
("")
# null
︙
;;
(*[!0-9]*)
# contains non-numeric character(s)
︙
;;
(*)
# is a whole number (non-negative integer)
︙
esac
もちろん、数字を除くすべての文字を意味する古い[!0-9]
シェル式はどこにありますか?[^0-9]
([!…]
両方とも[^…]
bashで動作します。
[!…]
動作するにはPOSIXが必要で、結果は[^…]
指定されていません。)文字列がどの種類の非数字であるかを問わない場合は、非数字モードを組み合わせることができます。
case "$1" in
("" | *[!0-9]*)
# not a number
︙
;;
(*)
# is a number
︙
esac
練習として、ここにcase
すべての種類の間違い(正確には1つ以上の数字で構成される文字列、オプションでピリオド()、およびオプションでマイナス.
記号())を処理するステートメントがあります。-
case "$1" in
(*[!-.0-9]*)
# contains non-numeric character(s)
;;
(*?-*)
# contains '-' somewhere other than the first position
;;
(*.*.*)
# contains multiple decimal points
;;
(*)
case "$1" in
(*[0-9]*)
# is a real number
;;
(*)
# not a number
esac
esac
文字列に実際に少なくとも1つの数字が含まれていることを確認するためにcase
-within-a-を追加しました。case
文字列が空であることをテストしたので、整数の例ではこれは必要ありませんでした。このステートメントからテストを削除しました。 2番目がない場合は、case
単一-
または単一.
(偶数-.
)が数字と見なされます。もちろん、これらの例外を処理するためにパターンを追加できますが、これは複雑になる可能性があります。 (たとえば、私はこの回答が例外の-.
1つであることに気付かずに公開することになっていました。)私は上記のアプローチがより柔軟で強力であると思います。
もちろん、数字以外のモードもここで組み合わせることができます
(*[!-.0-9]* | *?-* | *.*.*)
。
答え3
到着case
正規表現を使用した文の数値の一致、正規表現のワイルドカードサポートを持つシェルが必要です。私はこれでksh93だけを知っています。
ksh93 globを使用すると、globモードで拡張正規表現を実行または~(E)^[0-9]+$
使用したり、~(E:^[0-9]+$)
Perlに似た正規表現を使用したりできます(基本正規表現、高度正規表現、SysV正規表現でも機能します)。E
~(P)^\d+$
G
X
V
だから:
#! /bin/ksh93 -
for i do
case $i in
(~(E)^[0-9]+$)
n=$i;;
(*)
echo >&2 'Invalid argument!'
usage
esac
done