Flá*_*iro 543 linux bash shell
我无法弄清楚如何确保传递给我的脚本的参数是否为数字.
我想做的就是这样:
test *isnumber* $1 && VAR=$1 || echo "need a number"
Run Code Online (Sandbox Code Playgroud)
有帮助吗?
Cha*_*ffy 727
一种方法是使用正则表达式,如下所示:
re='^[0-9]+$'
if ! [[ $yournumber =~ $re ]] ; then
echo "error: Not a number" >&2; exit 1
fi
Run Code Online (Sandbox Code Playgroud)
如果该值不一定是整数,请考虑适当修改正则表达式; 例如:
^[0-9]+([.][0-9]+)?$
Run Code Online (Sandbox Code Playgroud)
...或者,处理带有符号的数字:
^[+-]?[0-9]+([.][0-9]+)?$
Run Code Online (Sandbox Code Playgroud)
jil*_*les 259
没有bashisms(即使在System V sh中工作),
case $string in
''|*[!0-9]*) echo bad ;;
*) echo good ;;
esac
Run Code Online (Sandbox Code Playgroud)
这会拒绝空字符串和包含非数字的字符串,接受其他所有内容.
负数或浮点数需要一些额外的工作.一个想法是排除-
/ .
在第一个"坏"模式中添加更多包含不恰当用途的"坏"模式(?*-*
/ *.*.*
)
Alb*_*gni 171
以下解决方案也可以在基本shell(如Bourne)中使用,而无需使用正则表达式.基本上任何使用非数字的数值评估操作都会导致错误,在shell中会将其隐式地视为false:
"$var" -eq "$var"
Run Code Online (Sandbox Code Playgroud)
如:
#!/bin/bash
var=a
if [ -n "$var" ] && [ "$var" -eq "$var" ] 2>/dev/null; then
echo number
else
echo not a number
fi
Run Code Online (Sandbox Code Playgroud)
你还可以测试$?更明确的操作的返回码:
[ -n "$var" ] && [ "$var" -eq "$var" ] 2>/dev/null
if [ $? -ne 0 ]; then
echo $var is not number
fi
Run Code Online (Sandbox Code Playgroud)
标准错误的重定向是隐藏bash打印出来的"整数表达式预期"消息,以防我们没有数字.
CAVEATS(感谢下面的评论):
[[ ]]
而不是[ ]
总是评估true
true
bash: [[: 1 a: syntax error in expression (error token is "a")
bash: [[: i: expression recursion level exceeded (error token is "i")
mru*_*cci 38
这测试一个数字是否为非负整数并且是独立于shell的(即没有bashisms)并且仅使用shell内置函数:
[ -z "${num##[0-9]*}" ] && echo "is a number" || echo "is not a number";
Run Code Online (Sandbox Code Playgroud)
但是错了.
正如jilles在他的回答中评论和建议的那样,这是使用shell模式的正确方法.
[ ! -z "${num##*[!0-9]*}" ] && echo "is a number" || echo "is not a number";
Run Code Online (Sandbox Code Playgroud)
gle*_*man 37
没有人建议使用bash的扩展模式匹配:
[[ $1 == ?(-)+([0-9]) ]] && echo "$1 is an integer"
Run Code Online (Sandbox Code Playgroud)
pix*_*eat 26
我对直接解析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
}
Run Code Online (Sandbox Code Playgroud)
将'%f'更改为您需要的任何特定格式.
F. *_*uri 17
(2) 完全重写此答案:2021 年 6 月 27 日。
对于不同类型的测试,有一些非常不同的方法。
我回顾了最相关的方法并建立了这个比较。
is_uint()
这些函数执行代码来评估表达式是否为无符号整数,即完全由数字组成。
使用参数扩展
(这是我之前的方法!)
isuint_Parm() { [ "$1" ] && [ -z "${1//[0-9]}" ] ;}
Run Code Online (Sandbox Code Playgroud)
使用叉子grep
isuint_Grep() { grep -qE '^[0-9]+$' <<<"$1"; }
Run Code Online (Sandbox Code Playgroud)
我只测试了一次这个方法,因为它很慢。这只是为了表明不该做什么。
使用bash整数功能
isuint_Bash() { (( 10#$1 >= 0 )) 2>/dev/null ;}
Run Code Online (Sandbox Code Playgroud)
使用 case
isuint_Case() { case $1 in ''|*[!0-9]*) return 1;;esac;}
Run Code Online (Sandbox Code Playgroud)
使用bash的正则表达式
isuint_Regx() { [[ $1 =~ ^[0-9]+$ ]] ;}
Run Code Online (Sandbox Code Playgroud)
is_int()
这些函数实现代码以评估表达式是否为有符号整数,即如上但允许在数字之前使用可选符号。
使用参数扩展
isint_Parm() { local chk=${1#[+-]}; [ "$chk" ] && [ -z "${chk//[0-9]}" ] ;}
Run Code Online (Sandbox Code Playgroud)
使用bash整数功能
isint_Bash() { (( 10#$1 )) 2>/dev/null ;}
Run Code Online (Sandbox Code Playgroud)
使用 case
isint_Case() { case ${1#[-+]} in ''|*[!0-9]*) return 1;;esac;}
Run Code Online (Sandbox Code Playgroud)
使用bash的正则表达式
isint_Regx() { [[ $1 =~ ^[+-]?[0-9]+$ ]] ;}
Run Code Online (Sandbox Code Playgroud)
is_num()
这些函数实现代码来评估表达式是否为浮点数,即如上但允许可选的小数点和后面的附加数字。这并不试图涵盖科学记数法中的数字表达式(例如 1.0234E-12)。
使用参数扩展
isnum_Parm() { local ck=${1#[+-]};ck=${ck/.};[ "$ck" ]&&[ -z "${ck//[0-9]}" ];}
Run Code Online (Sandbox Code Playgroud)
使用bash的正则表达式
isnum_Regx() { [[ $1 =~ ^[+-]?([0-9]+([.][0-9]*)?|\.[0-9]+)$ ]] ;}
Run Code Online (Sandbox Code Playgroud)
使用 case
isnum_Case() { case ${1#[-+]} in ''|.|*[!0-9.]*|*.*.*) return 1;; esac ;}
Run Code Online (Sandbox Code Playgroud)
(您可以在先前声明的函数之后复制/粘贴此测试代码。)
testcases=(
1 42 -3 +42 +3. .9 3.14 +3.141 -31.4 '' . 3-3 3.1.4 3a a3 blah 'Good day!'
);printf '%-12s %4s %4s %4s %4s %4s %4s %4s %4s %4s %4s %4s %4s\n' Function \
U{Prm,Grp,Bsh,Cse,Rgx} I{Prm,Bsh,Cse,Rgx} N{Prm,Cse,Rgx}; \
for var in "${testcases[@]}";do
outstr='';
for func in isuint_{Parm,Grep,Bash,Case,Regx} isint_{Parm,Bash,Case,Regx} \
isnum_{Parm,Case,Regx};do
if $func "$var"
then outstr+=' num'
else outstr+=' str'
fi
done
printf '%-11s %s\n' "|$var|" "$outstr"
done
Run Code Online (Sandbox Code Playgroud)
应该输出:
Function UPrm UGrp UBsh UCse URgx IPrm IBsh ICse IRgx NPrm NCse NRgx
|1| num num num num num num num num num num num num
|42| num num num num num num num num num num num num
|-3| str str str str str num num num num num num num
|+42| str str num str str num num num num num num num
|+3.| str str str str str str str str str num num num
|.9| str str str str str str str str str num num num
|3.14| str str str str str str str str str num num num
|+3.141| str str str str str str str str str num num num
|-31.4| str str str str str str str str str num num num
|| str str num str str str str str str str str str
|.| str str str str str str str str str str str str
|3-3| str str num str str str str str str str str str
|3.1.4| str str str str str str str str str str str str
|3a| str str str str str str str str str str str str
|a3| str str str str str str str str str str str str
|blah| str str str str str str str str str str str str
|Good day!| str str str str str str str str str str str str
Run Code Online (Sandbox Code Playgroud)
我希望!(注意:uint_bash
似乎并不完美!)
然后我构建了这个测试函数:
testFunc() {
local tests=1000 start=${EPOCHREALTIME//.}
for ((;tests--;)) ;do
"$1" "$3"
done
printf -v "$2" %u $((${EPOCHREALTIME//.}-start))
}
percent(){ local p=00$((${1}00000/$2));printf -v "$3" %.2f%% ${p::-3}.${p: -3};}
sortedTests() {
local func NaNTime NumTime ftyp="$1" nTest="$2" tTest="$3" min i pct line
local -a order=()
shift 3
for func ;do
testFunc "${ftyp}_$func" NaNTime "$tTest"
testFunc "${ftyp}_$func" NumTime "$nTest"
order[NaNTime+NumTime]=${ftyp}_$func\ $NumTime\ $NaNTime
done
printf '%-12s %11s %11s %14s\n' Function Number NaN Total
min="${!order[*]}" min=${min%% *}
for i in "${!order[@]}";do
read -ra line <<<"${order[i]}"
percent "$i" "$min" pct
printf '%-12s %9d\U00B5s %9d\U00B5s %12d\U00B5s %9s\n' \
"${line[@]}" "$i" "$pct"
done
}
Run Code Online (Sandbox Code Playgroud)
我可以这样跑:
sortedTests isuint "This is not a number." 31415926535897932384 \
Case Grep Parm Bash Regx ;\
sortedTests isint "This is not a number." 31415926535897932384 \
Case Parm Bash Regx ;\
sortedTests isnum "This string is clearly not a number..." \
3.141592653589793238462643383279502884 Case Parm Regx
Run Code Online (Sandbox Code Playgroud)
在我的主机上,这显示:
Function Number NaN Total
isuint_Case 6762µs 8492µs 15254µs 100.00%
isuint_Bash 13478µs 12739µs 26217µs 171.87%
isuint_Parm 11324µs 18807µs 30131µs 197.53%
isuint_Regx 20777µs 27616µs 48393µs 317.25%
isuint_Grep 1516390µs 1491751µs 3008141µs 19720.34%
Function Number NaN Total
isint_Case 8630µs 8042µs 16672µs 100.00%
isint_Bash 14254µs 12272µs 26526µs 159.10%
isint_Parm 16445µs 20491µs 36936µs 221.54%
isint_Regx 23661µs 28287µs 51948µs 311.59%
Function Number NaN Total
isnum_Case 9579µs 10328µs 19907µs 100.00%
isnum_Parm 21115µs 28983µs 50098µs 251.66%
isnum_Regx 35552µs 58453µs 94005µs 472.22%
Run Code Online (Sandbox Code Playgroud)
case
方法明明是最快的!regex
比使用参数扩展快3 倍,比使用参数扩展快 2倍 。grep
在不需要时应避免分叉(to或任何二进制文件)。case
方法成了我的首选:
is_uint() { case $1 in '' | *[!0-9]* ) return 1;; esac ;}
is_int() { case ${1#[-+]} in '' | *[!0-9]* ) return 1;; esac ;}
is_unum() { case $1 in '' | . | *[!0-9.]* | *.*.* ) return 1;; esac ;}
is_num() { case ${1#[-+]} in '' | . | *[!0-9.]* | *.*.* ) return 1;; esac ;}
Run Code Online (Sandbox Code Playgroud)
for shell in bash dash 'busybox sh' ksh zsh "$@";do
printf "%-12s " "${shell%% *}"
$shell < <(testScript) 2>&1 | xargs
done
Run Code Online (Sandbox Code Playgroud)
由此可见:
bash Success
dash Success
busybox Success
ksh Success
zsh Success
Run Code Online (Sandbox Code Playgroud)
据我所知,其他基于bash的解决方案,如regex和bash的整数在许多其他 shell 中不起作用,而且fork资源昂贵,我更喜欢这种case
方式(就在参数扩展之前,它也大多兼容)。
Ser*_*reu 15
我正在寻找答案,并意识到没有人想到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
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)
要匹配JUST整数,请使用:
# change check line to:
check=`echo "$1" | grep -E ^\-?[0-9]+$`
Run Code Online (Sandbox Code Playgroud)
tri*_*e_r 11
只是跟进@mary.但是因为我没有足够的代表,所以不能将其作为对该帖子的评论发布.无论如何,这是我用过的:
isnum() { awk -v a="$1" 'BEGIN {print (a == a + 0)}'; }
Run Code Online (Sandbox Code Playgroud)
如果参数是数字,函数将返回"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
Run Code Online (Sandbox Code Playgroud)
Hac*_*chi 11
对于我的问题,我只需要确保用户不会意外输入一些文本,因此我试图保持简单易读
isNumber() {
(( $1 )) 2>/dev/null
}
Run Code Online (Sandbox Code Playgroud)
根据手册页,这几乎可以满足我的要求
如果表达式的值非零,则返回状态为 0
为了防止“可能是数字”的字符串出现令人讨厌的错误消息,我忽略了错误输出
$ (( 2s ))
bash: ((: 2s: value too great for base (error token is "2s")
Run Code Online (Sandbox Code Playgroud)
Jos*_*hih 10
这可以通过使用grep
查看相关变量是否与扩展正则表达式匹配来实现。
1120
:yournumber=1120
if echo "$yournumber" | grep -qE '^[0-9]+$'; then
echo "Valid number."
else
echo "Error: not a number."
fi
Run Code Online (Sandbox Code Playgroud)
输出: Valid number.
1120a
:yournumber=1120a
if echo "$yournumber" | grep -qE '^[0-9]+$'; then
echo "Valid number."
else
echo "Error: not a number."
fi
Run Code Online (Sandbox Code Playgroud)
输出: Error: not a number.
grep
,该-E
开关允许我们使用扩展正则表达式'^[0-9]+$'
。这个正则表达式意味着变量应该只[]
包含0-9
从变量的^
开头到$
结尾的零到九的数字,并且应该至少有+
一个字符。grep
,在-q
安静的开关关闭任何输出是否发现任何东西。if
检查 的退出状态grep
。退出状态0
意味着成功,任何更大的都意味着错误。该grep
命令有一个退出状态,即0
是否找到匹配项,1
何时未找到;所以把它们放在一起,在if
测试中,我们echo
将变量$yournumber
和|
管道传递给grep
它,用-q
switch 悄悄地匹配-E
扩展的正则表达式'^[0-9]+$'
表达式。的退出状态grep
将是0
是否grep
成功找到匹配项,1
如果没有。如果匹配成功,我们echo "Valid number."
. 如果匹配失败,我们echo "Error: not a number."
.
我们可以将正则表达式从'^[0-9]+$'
更改'^[0-9]*\.?[0-9]+$'
为浮点数或双精度数。
1120.01
:yournumber=1120.01
if echo "$yournumber" | grep -qE '^[0-9]*\.?[0-9]+$'; then
echo "Valid number."
else
echo "Error: not a number."
fi
Run Code Online (Sandbox Code Playgroud)
输出: Valid number.
11.20.01
:yournumber=11.20.01
if echo "$yournumber" | grep -qE '^[0-9]*\.?[0-9]+$'; then
echo "Valid number."
else
echo "Error: not a number."
fi
Run Code Online (Sandbox Code Playgroud)
输出: Error: not a number.
要允许负整数,只需将正则表达式从 更改'^[0-9]+$'
为'^\-?[0-9]+$'
。
要允许负浮点数或双精度数,只需将正则表达式从 更改'^[0-9]*\.?[0-9]+$'
为'^\-?[0-9]*\.?[0-9]+$'
。
老问题,但我只想解决我的解决方案.这个不需要任何奇怪的shell技巧,或者依赖于永远不会存在的东西.
if [ -n "$(printf '%s\n' "$var" | sed 's/[0-9]//g')" ]; then
echo 'is not numeric'
else
echo 'is numeric'
fi
Run Code Online (Sandbox Code Playgroud)
基本上它只是从输入中删除所有数字,如果你留下一个非零长度的字符串,那么它不是一个数字.
test -z "${i//[0-9]}" && echo digits || echo no no no
Run Code Online (Sandbox Code Playgroud)
${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
Run Code Online (Sandbox Code Playgroud)
我使用expr。如果您尝试向非数字值添加零,它将返回非零值:
if expr -- "$number" + 0 > /dev/null 2>&1
then
echo "$number is a number"
else
echo "$number isn't a number"
fi
Run Code Online (Sandbox Code Playgroud)
如果您需要非整数,可能可以使用bc,但我不相信bc
有完全相同的行为。将零添加到非数字会使您为零,并且它也会返回零值。也许你可以结合bc
和expr
。用于bc
向 中添加零$number
。如果答案是0
,则尝试expr
验证它$number
不为零。
小智 6
@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
Run Code Online (Sandbox Code Playgroud)
尽管对于实数,在小数点之前没有数字是强制性的。
为了提供对浮点数和科学计数法的更彻底的支持(C / Fortran中的许多程序,否则将以这种方式导出浮点数),此行的有用补充如下:
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
Run Code Online (Sandbox Code Playgroud)
因此,如果您要查找任何特定类型,则可以找到一种区分数字类型的方法:
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
Run Code Online (Sandbox Code Playgroud)
注意:我们可以列出十进制和科学计数法的句法要求,其中之一是允许逗号作为小数点以及“。”。然后,我们断言必须只有一个这样的小数点。[Ee]浮点数中可以有两个+/-符号。我从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
Run Code Online (Sandbox Code Playgroud)
无法发表评论所以我会添加自己的答案,这是使用bash模式匹配的glenn jackman答案的扩展.
我最初需要的是识别数字并区分整数和浮点数.功能定义扣除为:
function isInteger() {
[[ ${1} == ?(-)+([0-9]) ]]
}
function isFloat() {
[[ ${1} == ?(-)@(+([0-9]).*([0-9])|*([0-9]).+([0-9]))?(E?(-|+)+([0-9])) ]]
}
Run Code Online (Sandbox Code Playgroud)
我使用单元测试(使用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
}
Run Code Online (Sandbox Code Playgroud)
注意:可以修改isFloat模式以更加容忍小数点(@(.,)
)和E符号(@(Ee)
).我的单元测试只测试整数或浮点值,但不测试任何无效输入.
一种简单的方法是检查它是否包含非数字字符。您将所有数字字符替换为空并检查长度。如果有长度,它就不是数字。
if [[ ! -n ${input//[0-9]/} ]]; then
echo "Input Is A Number"
fi
Run Code Online (Sandbox Code Playgroud)
小智 5
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
Run Code Online (Sandbox Code Playgroud)
数字将包括空格,小数点和浮点数的"e"或"E".
但是,如果指定C样式的十六进制数,即"0xffff"或"0XFFFF",[[:digit:]]将返回true.这里有一点陷阱,bash允许你做类似"0xAZ00"的东西并仍然把它算作一个数字(这不是来自GCC编译器的一些奇怪的怪癖,让你使用0x符号除16之外的基数??? )
如果您的输入完全不受信任,您可能希望在测试之前测试"0x"或"0X"是否为数字,除非您想接受十六进制数字.这将通过以下方式实现:
if [[ ${VARIABLE:1:2} = "0x" ]] || [[ ${VARIABLE:1:2} = "0X" ]]; then echo "$VAR is not numeric"; fi
Run Code Online (Sandbox Code Playgroud)
小智 5
我会试试这个:
printf "%g" "$var" &> /dev/null
if [[ $? == 0 ]] ; then
echo "$var is a number."
else
echo "$var is not a number."
fi
Run Code Online (Sandbox Code Playgroud)
注意:这将nan和inf识别为数字.
因为我最近不得不篡改这个,并且最喜欢karttu的单元测试方法。我修改了代码并添加了一些其他解决方案,自己尝试看看结果:
#!/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
Run Code Online (Sandbox Code Playgroud)
所以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; }
Run Code Online (Sandbox Code Playgroud)