我只是不知道如何确保传递给脚本的参数是否为数字。
我只想这样做:
test *isnumber* $1 && VAR=$1 || echo "need a number"
有什么帮助吗?
我只是不知道如何确保传递给脚本的参数是否为数字。
我只想这样做:
test *isnumber* $1 && VAR=$1 || echo "need a number"
有什么帮助吗?
当前回答
易于理解和兼容的解决方案,带有测试命令:
test $myVariable -eq 0 2>/dev/null
if [ $? -le 1 ]; then echo 'ok'; else echo 'KO'; fi
如果myVariable=0,则返回代码为0如果myVariable>0,则返回代码为1如果myVariable不是整数,则返回代码为2
其他回答
一种简单的方法是检查它是否包含非数字字符。您可以将所有数字字符替换为空,并检查长度。如果有长度,那不是数字。
if [[ ! -n ${input//[0-9]/} ]]; then
echo "Input Is A Number"
fi
因为我最近不得不修改这个,并且最喜欢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
因此,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; }
没有抨击(即使在System V sh中也有效),
case $string in
''|*[!0-9]*) echo bad ;;
*) echo good ;;
esac
这将拒绝空字符串和包含非数字的字符串,接受其他所有内容。
负数或浮点数需要一些额外的工作。一个想法是排除-/。在第一个“bad”模式中,添加更多包含不正确用法的“bad“模式(?*-*/*.*.*)
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样式十六进制数,即“0xffff”或“0xffff”,则[[:digital:]]返回true。这里有点陷阱,bash允许你做一些类似“0xAZ00”的事情,但仍然将其算作一个数字(这不是GCC编译器的一些奇怪的怪癖,允许你对16以外的基使用0x符号吗??)
如果您的输入完全不可信,除非您想接受十六进制数字,否则您可能需要在测试“0x”或“0x”之前测试它是否为数字。这将通过以下方式实现:
if [[ ${VARIABLE:1:2} = "0x" ]] || [[ ${VARIABLE:1:2} = "0X" ]]; then echo "$VAR is not numeric"; fi
快速和肮脏:我知道这不是最优雅的方式,但我通常只是在上面加一个零并测试结果。像这样:
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框架中最健壮的。。。