How do I test if a variable is a number in Bash?
我只是不知道如何确定传递给脚本的参数是否是数字。
我只想做这样的事情:
1 | test *isnumber* $1 && VAR=$1 || echo"need a number" |
有什么帮助吗?
一种方法是使用正则表达式,如:
1 2 3 4 | re='^[0-9]+$' if ! [[ $yournumber =~ $re ]] ; then echo"error: Not a number">&2; exit 1 fi |
如果该值不一定是整数,请考虑适当地修改regex;例如:
1 | ^[0-9]+([.][0-9]+)?$ |
…或者,用符号处理数字:
1 | ^[+-]?[0-9]+([.][0-9]+)?$ |
没有bashims(即使在系统v sh中也能工作)。
1 2 3 4 | case $string in ''|*[!0-9]*) echo bad ;; *) echo good ;; esac |
这将拒绝空字符串和包含非数字的字符串,并接受其他所有内容。
负数或浮点数需要做一些额外的工作。一种想法是在第一个"坏"模式中排除
以下解决方案也可以用于基本外壳,如Bourne,而不需要正则表达式。基本上,任何使用非数字的数值计算操作都将导致一个错误,在shell中该错误将被隐式地视为错误:
1 | "$var" -eq"$var" |
如:
1 2 3 4 5 6 7 8 9 | #!/bin/bash var=a if [ -n"$var" ] && ["$var" -eq"$var" ] 2>/dev/null; then echo number else echo not a number fi |
你也可以测试美元吗?更明确的操作返回代码:
1 2 3 4 | [ -n"$var" ] && ["$var" -eq"$var"] 2>/dev/null if [ $? -ne 0 ]; then echo $var is not number fi |
标准错误的重定向是为了隐藏bash在没有数字的情况下打印出来的"integer expression expected"消息。
注意事项(感谢下面的评论):
- 带小数点的数字未标识为有效的"数字"
- 使用
[[ ]] 而不是[ ] 将始终对true 进行评估。 - 大多数非bash shell总是将该表达式计算为
true - bash中的行为是未记录的,因此可能在没有警告的情况下发生更改。
- 如果该值包含数字后的空格(例如"1 A")会产生错误,如
bash: [[: 1 a: syntax error in expression (error token is"a") 。 - 如果该值与var name相同(例如i="i"),则会产生错误,如
bash: [[: i: expression recursion level exceeded (error token is"i") 。
这将测试一个数字是否为非负整数,是否与shell无关(即没有bashims),并且只使用shell内置的:
不正确。
因为第一个答案(下面)允许包含字符的整数,只要第一个不是变量中的第一个。
1 | [ -z"${num##[0-9]*}" ] && echo"is a number" || echo"is not a number"; |
对的。
正如Jilles在他的回答中评论和建议的那样,这是使用shell模式来实现这一点的正确方法。
1 | [ ! -z"${num##*[!0-9]*}" ] && echo"is a number" || echo"is not a number"; |
没有人建议bash的扩展模式匹配:
1 | [[ $1 == ?(-)+([0-9]) ]] && echo"$1 is an integer" |
我对直接在shell中解析数字格式的解决方案感到惊讶。Shell不太适合这样做,因为它是用于控制文件和进程的DSL。有足够多的数字解析器,下面稍微低一点,例如:
1 2 3 4 5 6 | 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"更改为所需的任何特定格式。
我在看答案…意识到没有人想到浮点数(带点)!
使用grep也很好。-e表示扩展regexp-Q表示安静(不回音)-QE是两者的结合。
直接在命令行中测试:
1 2 3 4 5 6 7 8 9 10 11 | $ 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脚本中使用:
1 2 3 4 5 6 7 8 9 | 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 |
要仅匹配整数,请使用以下命令:
1 2 | # change check line to: check=`echo"$1" | grep -E ^\-?[0-9]+$` |
只是对@mary的跟进。但因为我没有足够的代表,所以无法将此作为评论发布到该帖子中。不管怎样,我用的是:
1 | isnum() { awk -v a="$1" 'BEGIN {print (a == a + 0)}'; } |
如果参数是数字,函数将返回"1",否则将返回"0"。这既适用于整数,也适用于浮点。用法如下:
1 2 3 4 5 6 7 | n=-2.05e+07 res=`isnum"$n"` if ["$res" =="1" ]; then echo"$n is a number" else echo"$n is not a number" fi |
http://tldp.org/ldp/bash-初学者指南/html/sect__03.html
您还可以使用bash的字符类。
1 2 3 4 5 | if [[ $VAR = *[[:digit:]]* ]]; then echo"$VAR is numeric" else echo"$VAR is not numeric" fi |
数字包括空格、小数点和浮点数的"e"或"e"。
但是,如果指定了C样式的十六进制数,即"0xffff"或"0xffff",[:digit:]将返回true。这里有一个陷阱,bash允许你做一些类似于"0xaz00"的事情,并且仍然把它作为一个数字来计算(这不是来自GCC编译器的一些奇怪的怪癖,它允许你对16以外的基使用0x符号吗???)
如果您的输入完全不可信,您可能需要在测试它是否是数字之前测试"0x"或"0x",除非您想接受十六进制数字。这将通过以下方式实现:
1 | if [[ ${VARIABLE:1:2} ="0x" ]] || [[ ${VARIABLE:1:2} ="0X" ]]; then echo"$VAR is not numeric"; fi |
老问题,但我只想强调我的解决方案。这个不需要任何奇怪的贝壳技巧,也不需要依赖那些永远不存在的东西。
1 2 3 4 5 6 | if [ -n"$(printf '%s '"$var" | sed 's/[0-9]//g')" ]; then echo 'is not numeric' else echo 'is numeric' fi |
基本上,它只是从输入中删除所有数字,如果留下一个非零长度的字符串,那么它就不是一个数字。
1 | test -z"${i//[0-9]}" && echo digits || echo no no no |
如果还想排除当
1 2 | 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 |
1 | [[ $1 =~ ^-?[0-9]+$ ]] && echo"number" |
别忘了
还不能评论,所以我将添加我自己的答案,这是使用bash模式匹配对glenn jackman答案的扩展。
我最初的需要是识别数字,区分整数和浮点数。函数定义推导为:
1 2 3 4 5 6 7 | function isInteger() { [[ ${1} == ?(-)+([0-9]) ]] } function isFloat() { [[ ${1} == ?(-)@(+([0-9]).*([0-9])|*([0-9]).+([0-9]))?(E?(-|+)+([0-9])) ]] } |
我使用单元测试(使用shunit2)来验证我的模式是否按预期工作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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模式可以修改为对小数点(
我用EXPR。如果尝试向非数字值添加零,则返回非零:
1 2 3 4 5 6 | if expr --"$number" + 0 > /dev/null 2>&1 then echo"$number is a number" else echo"$number isn't a number" fi |
如果您需要非整数,可能可以使用bc,但我不相信
我想试试这个:
1 2 3 4 5 6 | printf"%g""$var" &> /dev/null if [[ $? == 0 ]] ; then echo"$var is a number." else echo"$var is not a number." fi |
注意:这将NAN和INF识别为数字。
@charles dufy和其他人已经给出了明确的答案。纯bash解决方案将使用以下内容:
1 2 3 4 5 6 7 | 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或其他语言中的程序将以这种方式导出浮点数),对这一行的有用补充如下:
1 2 3 4 5 6 7 | 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 |
因此,如果您要查找任何特定类型,可以使用一种方法来区分数字类型:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 |
注:我们可以列出十进制和科学记数法的语法要求,一种是允许逗号作为基数,以及"."。然后我们断言,这样的基点必须只有一个。一个[EE]浮动中可以有两个+/-符号。我从奥鲁的作品中学到了更多的规则,并对"e-1"和"0-0"等不好的字符串进行了测试。下面是我的regex/substring/expr工具,它们似乎支持:
1 2 3 4 5 6 7 8 | parse_num() { local r=`expr"$1" : '.*\([.,]\)' 2>/dev/null | tr -d ' '` nat='^[+-]?[0-9]+[.,]?$' \ dot="${1%[.,]*}${r}${1##*[.,]}" \ float='^[\+\-]?([.,0-9]+[Ee]?[-+]?|)[0-9]+$' [["$1" == $dot ]] && [["$1" =~ $float ]] || [["$1" =~ $nat ]] } # usage: parse_num -123.456 |
最简单的方法是检查它是否包含非数字字符。将所有数字字符替换为空,并检查长度。如果有长度,就不是数字。
1 2 3 | if [[ ! -n ${input//[0-9]/} ]]; then echo"Input Is A Number" fi |
因为我最近不得不修改这个,并且最喜欢Karttu的单元测试。我修改了代码并添加了一些其他解决方案,您自己试试看结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #!/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 " $(isNumber $value) ${bools[$?]} $(printf"isNumber(%s)" $value) done |
因此isNumber()包含破折号、逗号和指数符号,因此在整数和浮点数上返回true,而在另一方面,isFloat()在整数值上返回false,isinteger()在浮点数上同样返回false。为了您的方便,所有这些都是一句话:
1 2 3 4 | 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; } |
这可以通过使用
1 2 3 4 5 6 | yournumber=1120 if [ $(echo"$yournumber" | grep -qE '^[0-9]+$'; echo $?) -ne"0" ]; then echo"Error: not a number." else echo"Valid number." fi |
输出:
1 2 3 4 5 6 | yournumber=1120a if [ $(echo"$yournumber" | grep -qE '^[0-9]+$'; echo $?) -ne"0" ]; then echo"Error: not a number." else echo"Valid number." fi |
输出:
grep 和-E 开关允许我们使用扩展正则表达式'^[0-9]+$' 。这个正则表达式意味着变量应该只有[] 包含从^ 开始到变量$ 结束的数字0-9 0到9,并且至少有+ 一个字符。grep 和-q 静音开关关闭任何输出,无论是否发现任何东西。$? 是上一个已执行命令的退出状态。退出状态0 表示成功,任何更大的状态都表示错误。grep 命令如果发现匹配,则其退出状态为0 ;如果不匹配,则其退出状态为1 ;$() 是一个子shell,它允许我们执行另一个命令,然后使用输出。
综合起来,在
现在,在
对于float或double,我们只需将正则表达式从
1 2 3 4 5 6 | 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 |
输出:
1 2 3 4 5 6 | 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 |
输出:
要允许负整数,只需将正则表达式从
为了允许负浮点数或双精度数,只需将正则表达式从
我使用以下(整数):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ## ##### 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 |
这里用一个正则表达式来测试整个部分和小数部分,用一个点分隔。
1 2 3 4 5 6 7 8 | re="^[0-9]*[.]{0,1}[0-9]*$" if [[ $1 =~ $re ]] then echo"is numeric" else echo"Naahh, not numeric" fi |
我试过UltraSawBlade的配方,因为它对我来说似乎是最实用的,但无法使它发挥作用。最后,我设计了另一种方法,基于参数替换的其他方法,这次使用regex替换:
1 | [["${var//*([[:digit:]])}" ]]; && echo"$var is not numeric" || echo"$var is numeric" |
它删除$var中的every:digit:class字符,并检查是否留下空字符串,这意味着原始字符只是数字。
我喜欢这款车的特点是占地面积小,灵活性强。在这种形式中,它只适用于非分隔的、以10为基数的整数,尽管您肯定可以使用模式匹配来满足其他需求。
快速和肮脏:我知道这不是最优雅的方式,但我通常只是在它上面加一个零,然后测试结果。像这样:
1 2 3 4 5 6 7 8 9 | 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或bomb。例如:
1 2 3 4 5 6 7 8 9 10 | 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的regex——它们在bash框架中看起来最强大……
要检查的变量
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
我将printf用作上述的其他答案,如果您提供格式字符串"%f"或"%i",printf将为您进行检查。比重新检查更容易,语法简单简短,printf无处不在。所以在我看来,这是一个不错的选择——你也可以用下面的想法来检查一系列的事情,它不仅对检查数字有用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | declare -r CHECK_FLOAT="%f" declare -r CHECK_INTEGER="%i" ## Number - Number to check ## String - Number type to check ## 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 } |
跟进10月13日大卫W的回答,如果使用
1 2 3 4 | test_var=`expr $am_i_numeric \* 0` >/dev/null 2>&1 if ["$test_var" ="" ] then ...... |
如果是数字,乘以1得到相同的值(包括负数)。否则你会得到你可以测试的
要捕获负数:
1 2 3 4 5 6 | if [[ $1 == ?(-)+([0-9.]) ]] then echo number else echo not a number fi |
1 2 | printf '%b'"-123 ABC" | tr '[:space:]' '_' | grep -q '^-\?[[:digit:]]\+$' && echo"Integer." || echo"NOT integer." |
如果不接受负整数,则删除grep匹配模式中的
我喜欢阿尔贝托·扎卡尼的回答。
1 | if ["$var" -eq"$var" ] 2>/dev/null; then |
重要前提条件:-没有生成子层-未调用重新分析程序-大多数shell应用程序不使用实数
但是,如果
1 | if ["$var" -ge 0 ] 2> /dev/null; then .. |
对于我的问题,我只需要确保用户不会意外地输入某些文本,因此我试图保持它的简单和可读性。
1 2 3 | isNumber() { (( $1 )) 2>/dev/null } |
根据手册,这是我想要的
If the value of the expression is non-zero, the return status is 0
为了防止"可能是数字"的字符串出现错误消息,我忽略了错误输出
1 2 | $ (( 2s )) bash: ((: 2s: value too great for base (error token is"2s") |
您也可以这样使用"let":
1 2 3 4 5 6 7 8 9 10 | [ ~]$ 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+操作符,就像这个线程中的一些答案一样。
我发现了一个很短的版本:
1 2 3 4 5 | function isnum() { return `echo"$1" | awk -F" " '{print ($0 != $0+0)}'` } |
如果安装了Perl,那么这一行程序简单、可读且可扩展。
1 | perl -se 'exit($n !~ /\d+/)' -- -n=a |
这是一些测试
1 2 3 4 | perl -se 'exit($n !~ /\d+/)' -- -n=a; echo $? 1 perl -se 'exit($n !~ /\d+/)' -- -n=2; echo $? 0 |
这是很自我解释的,但这里有更多的信息
-E 支持评估-s 允许在…在这种情况下,-n 之后传递参数。!~ 是否定的regexp匹配运算符,因为bash中的0是成功的,所以如果-n 参数是一个数字,我们希望它成功退出。
您将希望用一个函数包装它,这里有一个更好的版本,可以读取浮动。
1 | is_number() { perl -se 'exit($n !~ /^\d+(\.\d+)?$/)' -- -n="$1"; } |
接受的答案在这里不起作用,我在用MacOS。以下代码有效:
1 2 3 4 5 | if [ $(echo"$number" | grep -c '^[0-9]\+$') = 0 ]; then echo"it is a number" else echo"not a number" fi |
Stack弹出一条消息,问我30+个答案后是否真的想回答?当然可以!!!!使用bash的新特性,这里是:(在评论之后,我做了一个更改)
function isInt() { ([[ $1 -eq $(( $1 + 0 )) ]] 2>/dev/null &&
[[ $1 != '' ]] && echo 1) || echo '' }
1 2 3 | function isInt() { ([[ $1 =~ ^[-+0-9]+$ ]] && [[ $1 -eq $(( $1 + 0 )) ]] 2>/dev/null && [[ $1 != '' ]] && echo 1) || echo '' } |
支持:
1 2 3 4 5 6 7 8 9 10 11 12 13 | ===============out-of-the-box================== 1. negative integers (true & arithmetic), 2. positive integers (true & arithmetic), 3. with quotation (true & arithmetic), 4. without quotation (true & arithmetic), 5. all of the above with mixed signs(!!!) (true & arithmetic), 6. empty string (false & arithmetic), 7. no value (false & arithmetic), 8. alphanumeric (false & no arithmetic), 9. mixed only signs (false & no arithmetic), ================problematic==================== 10. positive/negative floats with 1 decimal (true & NO arithmetic), 11. positive/negative floats with 2 or more decimals (FALSE & NO arithmetic). |
只有当结合使用过程替换(如
当测试表达式的结果错误时,我使用大写,但是,它应该是相反的!
"算术"的意思是bash可以像这个表达式中那样做数学:
我在数学表达式中使用"算术/非算术"时,参数的行为如预期,与预期相比,参数的行为不当时,使用"非算术"。
如你所见,只有10号和11号是有问题的!
很完美!
附言:注意,最流行的答案在案例9中失败了!
这有点粗糙的边缘,但有点新手友好。
1 2 3 4 5 6 | if [ $number -ge 0 ] then echo"Continue with code block" else echo"We matched 0 or $number is not a number" fi |
这将导致错误并打印"非法数字:",如果$number不是数字,但它不会从脚本中中断。奇怪的是,我找不到一个只测试整数的测试选项。这里的逻辑将匹配任何大于或等于0的数字。
下面是我编写的一个脚本,用于与Nagios的脚本集成,目前它工作正常
1 2 3 4 5 6 7 8 9 10 11 12 13 | #!/bin/bash # Script to test variable is numeric or not # Shirish Shukla # Pass arg1 as number a1=$1 a=$(echo $a1|awk '{if($1 > 0) print $1; else print $1"*-1"}') b=$(echo"scale=2;$a/$a + 1" | bc -l 2>/dev/null) if [[ $b > 1 ]] then echo"$1 is Numeric" else echo"$1 is Non Numeric" fi |
如:
1 2 3 4 5 6 7 8 | # sh isnumsks.sh "-22.22" -22.22 is Numeric # sh isnumsks.sh "22.22" 22.22 is Numeric # sh isnumsks.sh "shirish22.22" shirish22.22 is Non Numeric |