スクリプトに渡された引数が数値かどうかを確認するにはどうすればよいかわかりません。
私がやりたいのはこのようなことです。
test *isnumber* $1 && VAR=$1 || echo "need a number"
何か手助け?
1つの方法は、次のように正規表現を使うことです。
re='^[0-9]+$'
if ! [[ $yournumber =~ $re ]] ; then
echo "error: Not a number" >&2; exit 1
fi
値が必ずしも整数ではない場合は、正規表現を適切に修正することを検討してください。例えば:
^[0-9]+([.][0-9]+)?$
...または、符号付きの数字を処理するには
^[+-]?[0-9]+([.][0-9]+)?$
根拠がなければ(System V shでも動作します)、
case $string in
''|*[!0-9]*) echo bad ;;
*) echo good ;;
esac
これは空の文字列と数字以外の文字を含む文字列を拒否し、他のすべてを受け入れます。
負数または浮動小数点数には追加の作業が必要です。最初の "bad"パターンで-
/.
を除外し、不適切な使い方を含む "bad"パターンを追加するという考えがあります(?*-*
/*.*.*
)
以下の解決策は、正規表現を必要とせずにBourneなどの基本的なシェルでも使用できます。基本的に非数値を使った数値評価操作はエラーになりますが、これはShellでは暗黙のうちにfalseとみなされます。
"$var" -eq "$var"
のように:
#!/bin/bash
var=a
if [ -n "$var" ] && [ "$var" -eq "$var" ] 2>/dev/null; then
echo number
else
echo not a number
fi
あなたはまた$のためにテストすることができますか?より明示的な操作の戻りコード
[ -n "$var" ] && ["$var" -eq "$var"] 2>/dev/null
if [ $? -ne 0 ]; then
echo $var is not number
fi
標準エラーのリダイレクトは、数値がない場合にbashが出力する「integer expression expected」メッセージを隠すためにあります。
_警告_ (下記のコメントのおかげで):
[[ ]]
の代わりに[ ]
を使用すると、常にtrue
と評価されます。true
として評価します。bash: [[: 1 a: syntax error in expression (error token is "a")
のように、数値の後にスペースが含まれている場合(例: "1 a")はエラーになります。bash: [[: i: expression recursion level exceeded (error token is "i")
のようにエラーになります。これは、数値が負でない整数であり、シェルから独立しているか(つまり、bashismsなしで)、シェル組み込みのみを使用するかどうかをテストします。
不正です。
この最初の答え(下記)では、最初の変数が変数の先頭ではない限り、文字を含む整数を使用できます。
[ -z "${num##[0-9]*}" ] && echo "is a number" || echo "is not a number";
_正しい_ 。
jilles はコメントし、 彼の答えで提案しました これはシェルパターンを使用してそれを行うための正しい方法です。
[ ! -z "${num##*[!0-9]*}" ] && echo "is a number" || echo "is not a number";
Bashの 拡張パターンマッチングを提案する人は誰もいません :
[[ $1 == ?(-)+([0-9]) ]] && echo "$1 is an integer"
Shellの数値フォーマットを直接解析するソリューションには驚いています。 Shellはこれにはあまり適していません。ファイルとプロセスを制御するためのDSLです。もう少し下位に十分な数のパーサーがあります。例えば:
isdecimal() {
# filter octal/hex/ord()
num=$(printf '%s' "$1" | sed "s/^0*\([1-9]\)/\1/; s/'/^/")
test "$num" && printf '%f' "$num" >/dev/null 2>&1
}
'%f'を必要な特定の形式に変更してください。
私は答えを見ていました、そして、誰も(ドットで)FLOAT数について考えなかったことに気付きました!
Grepを使うのも素晴らしいです。
- Eは拡張正規表現を意味します
- qは静かを意味します(エコーしません)。
- qEは両方の組み合わせです。
コマンドラインで直接テストするには
$ echo "32" | grep -E ^\-?[0-9]?\.?[0-9]+$
# answer is: 32
$ echo "3a2" | grep -E ^\-?[0-9]?\.?[0-9]+$
# answer is empty (false)
$ echo ".5" | grep -E ^\-?[0-9]?\.?[0-9]+$
# answer .5
$ echo "3.2" | grep -E ^\-?[0-9]?\.?[0-9]+$
# answer is 3.2
Bashスクリプトで使う:
check=`echo "$1" | grep -E ^\-?[0-9]*\.?[0-9]+$`
if [ "$check" != '' ]; then
# it IS numeric
echo "Yeap!"
else
# it is NOT numeric.
echo "nooop"
fi
JUST整数と一致させるには、これを使います。
# change check line to:
check=`echo "$1" | grep -E ^\-?[0-9]+$`
@maryへのフォローアップ。しかし、私は十分な担当者を持っていないので、その記事へのコメントとしてこれを投稿することができませんでした。とにかく、これが私が使ったものです。
isnum() { awk -v a="$1" 'BEGIN {print (a == a + 0)}'; }
引数が数値の場合、この関数は "1"を返し、それ以外の場合は "0"を返します。これは浮動小数点数と同様に整数に対しても働きます。使い方は次のようなものです。
n=-2.05e+07
res=`isnum "$n"`
if [ "$res" == "1" ]; then
echo "$n is a number"
else
echo "$n is not a number"
fi
test -z "${i//[0-9]}" && echo digits || echo no no no
${i//[0-9]}
は、$i
の値に含まれる任意の数字を空の文字列に置き換えます。man -P 'less +/parameter\/' bash
を参照してください。 -z
は、結果の文字列の長さがゼロかどうかを確認します。
$i
が空の場合もこのケースを除外したい場合は、以下のいずれかの構成を使用できます。
test -n "$i" && test -z "${i//[0-9]}" && echo digits || echo not a number
[[ -n "$i" && -z "${i//[0-9]}" ]] && echo digits || echo not a number
http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_04_03.html
Bashの文字クラスも使えます。
if [[ $VAR = *[[:digit:]]* ]]; then
echo "$VAR is numeric"
else
echo "$VAR is not numeric"
fi
数値には、スペース、小数点、および浮動小数点の場合は「e」または「E」が含まれます。
しかし、Cスタイルの16進数、つまり "0xffff"または "0XFFFF"を指定した場合、[[:digit:]]はtrueを返します。ここでちょっとした罠、bashはあなたが "0xAZ00"のようなことをすることを可能にし、それでも数字として数えます(16以外のベースに0x記法を使わせたGCCコンパイラの奇妙なことからではありませんか。 )
入力が完全に信頼されていない場合は、テストの前に "0x"または "0X"をテストして数値になるかどうかをテストすることをお勧めします。それは以下によって達成されるでしょう:
if [[ ${VARIABLE:1:2} = "0x" ]] || [[ ${VARIABLE:1:2} = "0X" ]]; then echo "$VAR is not numeric"; fi
昔の質問ですが、私は自分の解決策に取り組みたいと思いました。これは、奇妙なシェルトリックを必要としないか、永遠に存在しなかった何かに頼りません。
if [ -n "$(printf '%s\n' "$var" | sed 's/[0-9]//g')" ]; then
echo 'is not numeric'
else
echo 'is numeric'
fi
基本的にそれは単に入力からすべての数字を削除します、そしてあなたがゼロでない長さの文字列で残っているならそれは数字ではありませんでした。
[[ $1 =~ ^-?[0-9]+$ ]] && echo "number"
負の数を含めるために-
を忘れないでください。
私はこれを試してみます:
printf "%g" "$var" &> /dev/null
if [[ $? == 0 ]] ; then
echo "$var is a number."
else
echo "$var is not a number."
fi
注:これはnanとinfを数値として認識します。
まだコメントできないので、私は自分の答えを追加します。これは、bashパターン・マッチングを使用したglenn jackmanの答えの拡張です。
私が最初に必要としていたのは、数字を識別し、整数と浮動小数点数を区別することでした。関数定義は次のように推論しました。
function isInteger() {
[[ ${1} == ?(-)+([0-9]) ]]
}
function isFloat() {
[[ ${1} == ?(-)@(+([0-9]).*([0-9])|*([0-9]).+([0-9]))?(E?(-|+)+([0-9])) ]]
}
意図したとおりに動作するパターンを検証するために、ユニットテスト(shUnit2を使用)を使用しました。
oneTimeSetUp() {
int_values="0 123 -0 -123"
float_values="0.0 0. .0 -0.0 -0. -.0 \
123.456 123. .456 -123.456 -123. -.456
123.456E08 123.E08 .456E08 -123.456E08 -123.E08 -.456E08 \
123.456E+08 123.E+08 .456E+08 -123.456E+08 -123.E+08 -.456E+08 \
123.456E-08 123.E-08 .456E-08 -123.456E-08 -123.E-08 -.456E-08"
}
testIsIntegerIsFloat() {
local value
for value in ${int_values}
do
assertTrue "${value} should be tested as integer" "isInteger ${value}"
assertFalse "${value} should not be tested as float" "isFloat ${value}"
done
for value in ${float_values}
do
assertTrue "${value} should be tested as float" "isFloat ${value}"
assertFalse "${value} should not be tested as integer" "isInteger ${value}"
done
}
注:isFloatパターンは、小数点(@(.,)
)およびE記号(@(Ee)
)についてより耐性があるように変更できます。私のユニットテストは整数か浮動小数点数のいずれかの値のみをテストしますが、無効な入力はテストしません。
expr を使います。ゼロ以外の値にゼロを追加しようとすると、ゼロ以外の値が返されます。
if expr -- "$number" + 0 > /dev/null 2>&1
then
echo "$number is a number"
else
echo "$number isn't a number"
fi
非整数が必要な場合は bc を使用することは可能かもしれませんが、bc
がまったく同じ動作をするとは思わないゼロ以外の数にゼロを追加するとゼロになり、ゼロの値も返されます。たぶんあなたはbc
とexpr
を組み合わせることができます。 bc
を使用して$number
にゼロを追加します。答えが0
であれば、expr
を試して$number
がゼロでないことを確認してください。
私は最近これを改ざんしなければならなかったので、 karttu's のように単体テストで近づきます。私はコードを修正し、他の解決策も追加しました。結果を見るために自分で試してみてください。
#!/bin/bash
# N={0,1,2,3,...} by syntaxerror
function isNaturalNumber()
{
[[ ${1} =~ ^[0-9]+$ ]]
}
# Z={...,-2,-1,0,1,2,...} by karttu
function isInteger()
{
[[ ${1} == ?(-)+([0-9]) ]]
}
# Q={...,-½,-¼,0.0,¼,½,...} by karttu
function isFloat()
{
[[ ${1} == ?(-)@(+([0-9]).*([0-9])|*([0-9]).+([0-9]))?(E?(-|+)+([0-9])) ]]
}
# R={...,-1,-½,-¼,0.E+n,¼,½,1,...}
function isNumber()
{
isNaturalNumber $1 || isInteger $1 || isFloat $1
}
bools=("TRUE" "FALSE")
int_values="0 123 -0 -123"
float_values="0.0 0. .0 -0.0 -0. -.0 \
123.456 123. .456 -123.456 -123. -.456 \
123.456E08 123.E08 .456E08 -123.456E08 -123.E08 -.456E08 \
123.456E+08 123.E+08 .456E+08 -123.456E+08 -123.E+08 -.456E+08 \
123.456E-08 123.E-08 .456E-08 -123.456E-08 -123.E-08 -.456E-08"
false_values="blah meh mooh blah5 67mooh a123bc"
for value in ${int_values} ${float_values} ${false_values}
do
printf " %5s=%-30s" $(isNaturalNumber $value) ${bools[$?]} $(printf "isNaturalNumber(%s)" $value)
printf "%5s=%-24s" $(isInteger $value) ${bools[$?]} $(printf "isInteger(%s)" $value)
printf "%5s=%-24s" $(isFloat $value) ${bools[$?]} $(printf "isFloat(%s)" $value)
printf "%5s=%-24s\n" $(isNumber $value) ${bools[$?]} $(printf "isNumber(%s)" $value)
done
したがって、 isNumber() はダッシュ、コンマ、指数表記を含むため、整数と浮動小数点数ではTRUEを返します。一方、 isFloat() は整数値ではFALSEを返し、 isInteger( ) フロートでも同様にFALSEを返します。あなたの便宜のために、一つのライナーとしてすべて:
isNaturalNumber() { [[ ${1} =~ ^[0-9]+$ ]]; }
isInteger() { [[ ${1} == ?(-)+([0-9]) ]]; }
isFloat() { [[ ${1} == ?(-)@(+([0-9]).*([0-9])|*([0-9]).+([0-9]))?(E?(-|+)+([0-9])) ]]; }
isNumber() { isNaturalNumber $1 || isInteger $1 || isFloat $1; }
最も簡単な方法は、数字以外の文字が含まれているかどうかを確認することです。あなたはすべての数字を何も置き換えずに長さをチェックします。長さがあればそれは数字ではありません。
if [[ ! -n ${input//[0-9]/} ]]; then
echo "Input Is A Number"
fi
明確な答えは@charles Dufyらによって既に与えられています。純粋なbashソリューションは以下を使用するでしょう:
string="-12,345"
if [[ "$string" =~ ^-?[0-9]+[.,]?[0-9]*$ ]]
then
echo $string is a number
else
echo $string is not a number
fi
実数の場合、 基数点 の前に番号を付けることは必須ではありません。
浮動小数点数と科学的記数法(C/Fortranなどの多くのプログラムはこの方法でfloatをエクスポートする)をより完全にサポートするために、この行に追加すると便利です。
string="1.2345E-67"
if [[ "$string" =~ ^-?[0-9]*[.,]?[0-9]*[eE]?-?[0-9]+$ ]]
then
echo $string is a number
else
echo $string is not a number
fi
特定の型を探しているのであれば、数字の型を区別する方法になります。
string="-12,345"
if [[ "$string" =~ ^-?[0-9]+$ ]]
then
echo $string is an integer
Elif [[ "$string" =~ ^-?[0-9]*[.,]?[0-9]*$ ]]
then
echo $string is a float
Elif [[ "$string" =~ ^-?[0-9]*[.,]?[0-9]*[eE]-?[0-9]+$ ]]
then
echo $string is a scientific number
else
echo $string is not a number
fi
注:10進数表記と科学表記の構文要件をリストできます。1つは、基数としてコンマを使用できることと、「。」です。そして、そのような基数点は1つだけでなければならないと主張します。 [Ee] floatには2つの+/-符号があります。私はAuluの仕事からさらにいくつかの規則を学び、 '' ' - ' '-E-1' '0-0'のような悪い文字列に対してテストしました。これが我慢できそうな私のregex/substring/exprツールです:
parse_num() {
local r=`expr "$1" : '.*\([.,]\)' 2>/dev/null | tr -d '\n'`
nat='^[+-]?[0-9]+[.,]?$' \
dot="${1%[.,]*}${r}${1##*[.,]}" \
float='^[\+\-]?([.,0-9]+[Ee]?[-+]?|)[0-9]+$'
[[ "$1" == $dot ]] && [[ "$1" =~ $float ]] || [[ "$1" =~ $nat ]]
} # usage: parse_num -123.456
これは、grep
を使用して、問題の変数が拡張正規表現と一致するかどうかを確認することで実現できます。
1120
:yournumber=1120
if [ $(echo "$yournumber" | grep -qE '^[0-9]+$'; echo $?) -ne "0" ]; then
echo "Error: not a number."
else
echo "Valid number."
fi
出力:Valid number.
1120a
のテスト:yournumber=1120a
if [ $(echo "$yournumber" | grep -qE '^[0-9]+$'; echo $?) -ne "0" ]; then
echo "Error: not a number."
else
echo "Valid number."
fi
出力:Error: not a number.
grep
、-E
スイッチを使用すると、拡張正規表現'^[0-9]+$'
を使用できます。この正規表現は、変数が[]
のみを含み、変数の0-9
から^
終わりまでの$
ゼロから9までの数字を含み、少なくとも+
1文字。grep
、-q
quietスイッチは、何かを検出したかどうかにかかわらず、出力をオフにします。$?
は、前に実行されたコマンドの終了ステータスです。終了ステータス0
は成功を意味し、それ以上はエラーを意味します。 grep
コマンドの終了ステータスは、一致する場合は0
、一致しない場合は1
です。$()
は、別のコマンドを実行して出力を使用できるサブシェルです。それをすべてまとめて、$()
サブシェルで、echo
変数$yournumber
と|
をgrep
にパイプして、-q
スイッチは、-E
拡張正規表現'^[0-9]+$'
式と暗黙的に一致します。次に、echo
$?
終了ステータス。grep
が正常に一致した場合は0
、一致しなかった場合は1
になります。
ここで、$()
サブシェルの外でif
条件に戻って、$()
サブシェルからの0
または1
の出力を取得し、 -ne
は"0"
と等しくありません。一致しなかった場合、終了ステータスは1
になり、一致しない"0"
になります。次に、echo "Error: not a number."
を実行します。一致に成功した場合、終了ステータスの出力は0
に等しく"0"
になり、それ以外の場合はecho "Valid number."
になります。
Floatまたはdoubleの正規表現を'^[0-9]+$'
から'^[0-9]*+\.?[0-8]+$'
に変更するだけです。
1120.01
:yournumber=1120.01
if [ $(echo "$yournumber" | grep -qE '^[0-9]*+\.?[0-8]+$'; echo $?) -ne "0" ]; then
echo "Error: not a number."
else
echo "Valid number."
fi
出力:Valid number.
11.20.01
:yournumber=11.20.01
if [ $(echo "$yournumber" | grep -qE '^[0-9]*+\.?[0-8]+$'; echo $?) -ne "0" ]; then
echo "Error: not a number."
else
echo "Valid number."
fi
出力:Error: not a number.
負の整数を許可するには、正規表現を'^[0-9]+$'
から'^\-?[0-9]+$'
に変更するだけです。
負のfloatまたはdoubleを許可するには、正規表現を'^[0-9]*+\.?[0-8]+$'
から'^\-?[0-9]*+\.?[0-8]+$'
に変更するだけです。
Alberto Zaccagniの回答が好きです。
if [ "$var" -eq "$var" ] 2>/dev/null; then
重要な前提条件: - サブシェルが生成されていない - REパーサーが呼び出されていない - ほとんどのシェルアプリケーションが実数を使用していない
$var
が複雑で(連想配列へのアクセスなど)、その数が負でない整数になる場合(ほとんどの場合)、これはおそらくより効率的ですか?
if [ "$var" -ge 0 ] 2> /dev/null; then ..
ここで同じことを、ドットで区切った部分全体と小数部分をテストする正規表現で行いました。
re="^[0-9]*[.]{0,1}[0-9]*$"
if [[ $1 =~ $re ]]
then
echo "is numeric"
else
echo "Naahh, not numeric"
fi
それが私にとって最も実用的であると思われたので、私はultrasawbladeのレシピを試してみました、そしてそれを働かせることができませんでした。結局、私は別の方法を考え出しました。パラメータ置換の他のものと同様に、今回は正規表現の置き換えです。
[[ "${var//*([[:digit:]])}" ]]; && echo "$var is not numeric" || echo "$var is numeric"
$ varのすべての:digit:class文字を削除し、空の文字列が残っているかどうかをチェックします。つまり、元の文字は数字のみであることを意味します。
私がこれについて好きなのは、その小さなフットプリントと柔軟性です。この形式では、他のニーズに合うようにパターンマッチングを使用することができますが、区切りのない10進整数に対してのみ機能します。
あなたも "let"を次のように使うことができます:
[ ~]$ var=1
[ ~]$ let $var && echo "It's a number" || echo "It's not a number"
It\'s a number
[ ~]$ var=01
[ ~]$ let $var && echo "It's a number" || echo "It's not a number"
It\'s a number
[ ~]$ var=toto
[ ~]$ let $var && echo "It's a number" || echo "It's not a number"
It\'s not a number
[ ~]$
しかし、私はこのスレッドでいくつかの答えのように "=〜" Bash 3+演算子を使うのが好きです。
チェックする変数
number=12345
またはnumber=-23234
またはnumber=23.167
またはnumber=-345.234
数値または非数値をチェック
echo $number | grep -E '^-?[0-9]*\.?[0-9]*$' > /dev/null
上記の終了ステータスに基づいて、さらなるアクションを決定します
if [ $? -eq 0 ]; then echo "Numeric"; else echo "Non-Numeric"; fi
David Wの回答 13年10月からのフォローアップ、expr
name__を使用する場合、これはより良いかもしれません
test_var=`expr $am_i_numeric \* 0` >/dev/null 2>&1
if [ "$test_var" = "" ]
then
......
数値の場合、1を掛けると同じ値になります(負数を含む)。そうでなければ、あなたはnull
name__を手に入れることができます。
フォーマット文字列 "%f"または "%i"を指定した場合は、他の回答としてprintfを使用します。printfがチェックを行います。チェックをやり直すよりも簡単で、構文は単純で短く、printfはいたるところにあります。だから私の考えではそれはまともな選択です - あなたはまた物事の範囲をチェックするために次のアイデアを使うことができます、それは数をチェックするのに役立つだけではありません。
declare -r CHECK_FLOAT="%f"
declare -r CHECK_INTEGER="%i"
## <arg 1> Number - Number to check
## <arg 2> String - Number type to check
## <arg 3> String - Error message
function check_number() {
local NUMBER="${1}"
local NUMBER_TYPE="${2}"
local ERROR_MESG="${3}"
local -i PASS=1
local -i FAIL=0
case "${NUMBER_TYPE}" in
"${CHECK_FLOAT}")
if ((! $(printf "${CHECK_FLOAT}" "${NUMBER}" &>/dev/random;echo $?))); then
echo "${PASS}"
else
echo "${ERROR_MESG}" 1>&2
echo "${FAIL}"
fi
;;
"${CHECK_INTEGER}")
if ((! $(printf "${CHECK_INTEGER}" "${NUMBER}" &>/dev/random;echo $?))); then
echo "${PASS}"
else
echo "${ERROR_MESG}" 1>&2
echo "${FAIL}"
fi
;;
*)
echo "Invalid number type format: ${NUMBER_TYPE} to check_number()." 1>&2
echo "${FAIL}"
;;
esac
}
>$ var=45
>$ (($(check_number $var "${CHECK_INTEGER}" "Error: Found $var - An integer is required."))) && { echo "$var+5" | bc; }
負の数を捉えるには:
if [[ $1 == ?(-)+([0-9.]) ]]
then
echo number
else
echo not a number
fi
私はかなり短いバージョンを見つけました:
function isnum()
{
return `echo "$1" | awk -F"\n" '{print ($0 != $0+0)}'`
}
printf '%b' "-123\nABC" | tr '[:space:]' '_' | grep -q '^-\?[[:digit:]]\+$' && echo "Integer." || echo "NOT integer."
負の整数を受け付けない場合は、grepマッチングパターンの-\?
を削除してください。
私の問題では、ユーザーが誤ってテキストを入力していないことを確認する必要があるので、シンプルで読みやすいようにしました。
isNumber() {
(( $1 )) 2>/dev/null
}
Manページによれば、これは私が欲しいことをほとんどします。
式の値がゼロ以外の場合、戻り状況は0です。
「数字の可能性があります」という文字列に対する厄介なエラーメッセージを防ぐために、エラー出力は無視します。
$ (( 2s ))
bash: ((: 2s: value too great for base (error token is "2s")
Quick&Dirty:それが最もエレガントな方法ではないことは知っていますが、通常はゼロを追加して結果をテストします。そのようです:
function isInteger {
[ $(($1+0)) != 0 ] && echo "$1 is a number" || echo "$1 is not a number"
}
x=1; isInteger $x
x="1"; isInteger $x
x="joe"; isInteger $x
x=0x16 ; isInteger $x
x=-32674; isInteger $x
$ 1が整数でない場合、$(($ 1 + 0))は0または爆弾を返します。例えば:
function zipIt { # quick Zip - unless the 1st parameter is a number
ERROR="not a valid number. "
if [ $(($1+0)) != 0 ] ; then # isInteger($1)
echo " backing up files changed in the last $1 days."
OUT="zipIt-$1-day.tgz"
find . -mtime -$1 -type f -print0 | xargs -0 tar cvzf $OUT
return 1
fi
showError $ERROR
}
注:スクリプト全体が爆弾になるようなフロートや混在型をチェックすることは考えていなかったと思います。 mrucciのソリューションとDuffyの正規表現を試してみるつもりです - それらはbashフレームワークの中で最も堅牢なようです...
私は次のものを使う(整数の場合):
## ##### constants
##
## __TRUE - true (0)
## __FALSE - false (1)
##
typeset -r __TRUE=0
typeset -r __FALSE=1
## --------------------------------------
## isNumber
## check if a value is an integer
## usage: isNumber testValue
## returns: ${__TRUE} - testValue is a number else not
##
function isNumber {
typeset TESTVAR="$(echo "$1" | sed 's/[0-9]*//g' )"
[ "${TESTVAR}"x = ""x ] && return ${__TRUE} || return ${__FALSE}
}
isNumber $1
if [ $? -eq ${__TRUE} ] ; then
print "is a number"
fi
Perlがインストールされていれば、この1つのライナーはシンプルで読みやすく拡張性があります。
Perl -se 'exit($n !~ /\d+/)' -- -n=a
ここにいくつかのテストがあります
Perl -se 'exit($n !~ /\d+/)' -- -n=a; echo $?
1
Perl -se 'exit($n !~ /\d+/)' -- -n=2; echo $?
0
それはかなり自己説明的ですが、ここでより多くの情報があります
-e
は評価を有効にします-s
は後に引数を渡すことを可能にします - この場合-n
!~
は否定正規表現の一致演算子です。引数-n
が数値の場合は正常終了しますこれを関数でラップするとよいでしょう。ここではfloatを読むことができるより良いバージョンです。
is_number() { Perl -se 'exit($n !~ /^\d+(\.\d+)?$/)' -- -n="$1"; }