
以下のように変数が4桁以上かどうかをテストしたいと思います。
#!/bin/bash
if [ $input has more than 4 digits ]; then
echo " * Please only 4 digits" >&2
echo""
else
the other option
fi
答え1
(数値ではなく)ビット数に興味がある場合は、Bash / Ksh / Zshの正規表現と一致させることができます(*脚注を参照[[:digit:]]
)。
#!/bin/bash
input=$1
re='^[[:digit:]]{1,4}$'
if [[ $input =~ $re ]]; then
echo "'$input' contains 1 to 4 digits (and nothing else)"
else
echo "'$input' contains something else"
fi
または、たとえば、[[ $input =~ ^[[:digit:]]{5,}$ ]]
「5つ以上の数字(他の数字なし)」などを確認します。
case
または、純粋なPOSIXシェルではパターンマッチングを使用する必要があります。
#!/bin/sh
input=$1
case $input in
*[![:digit:]]*) onlydigits=0;; # contains non-digits
*[[:digit:]]*) onlydigits=1;; # at least one digit
*) onlydigits=0;; # empty
esac
if [ $onlydigits = 0 ]; then
echo "'$input' is empty or contains something other than digits"
elif [ "${#input}" -le 4 ]; then
echo "'$input' contains 1 to 4 digits (and nothing else)"
else
echo "'$input' contains 5 or more digits (but nothing else)"
fi
(すべてのロジックを中に入れることができますがcase
、if
そこに入れ子にするのは私の考えには少し見苦しいです。)
これは[[:digit:]]
現在のロケールの「数値」の概念と一致する必要があります。これはASCII番号を超えることも、超えないこともあります0123456789
。私のシステムでは、[[:digit:]]
⁴(上付きの4、U + 2074)は一致しませんが、[0-9]
一致します。他の「数字」を一致させることは問題になる可能性があります。シェルの数に対して算術演算を実行する場合。したがって、より厳密に適用するには、[0123456789]
ASCII番号のみを許可を使用してください。
答え2
これは、ASCII 10進数のみを意味し、他のタイプの10進数または10進数以外の数字は意味しないと仮定します。
shopt -s extglob # enables a subset of ksh extended globs including *(...),
# +(...) and ?(...) but unfortunately not {4}(...)
d='[0123456789]' nd='[^0123456789]'
case $input in
( $d$d$d$d+($d) ) echo made of more than 4 digits;;
( *$d*$d*$d*$d*$d* ) echo contains more than 4 digits;;
( "" ) echo empty;;
( *($nd) ) echo does not contain any digit;;
( *$nd* ) echo no more than 4 digits but also contains non-digits;;
( $d?($d)?($d)?($d) ) echo made of 1 to 4 digits;;
( * ) echo should not be reached;;
esac
bash
システムとロケールによっては0123456789以降と一致する可能性があるため、入力の検証には使用しないでください(詳細[0-9]
は[[:digit:]]
これは他の質問に対する答えです例えば)。
またbash
パターンマッチングは、マルチバイトロケールで非常に素晴らしい方法で機能します。。
たとえば、zh_CN.gb18030
中国語のロケールはinput='1-©©'
期待どおりに返されますが、シングルバイト()no more than 4 digits but also contains non-digits
を追加すると返されます。0x80
input='1-©©'$'\x80'
contains more than 4 digits
この理由(そして多くのシェルのコーナーケースにパターンマッチングがバグを持っているという事実)のために、入力検証のために可能なときはいつでも許可するために(ネガティブマッチングではなく)ポジティブマッチング(ネガティブマッチングとは反対)を使用する方がいいですね。 )拒否したい項目について)1 したがって、$d?($d)?($d)?($d)
必須ではありませんが、少なくとも理論的には、他の項目は前のパターンと一致する必要があります。
1 例外的に、Bourne シェルと Korn シェルの欠点を考慮することもできます。このシェルcase $input in [x]) echo yes; esac
は!x
[x]
答え3
やるよ
#!/usr/bin/env bash
die () { echo "$*" >&2; exit 1; }
input=$1
[[ $input == +([[:digit:]]) ]] || die "only digits please"
(( input <= 9999 )) || die "no more than 4 digits please"
echo "ok: $input"
答え4
別の方法は次のとおりです。
#!/bin/bash
if test -z "$1"
then
echo no digit supplied
elif grep -qE '[[:digit:]]{5}' <<< "$1"
then
echo too many digits supplied
else
echo number of digits ok
fi