我只是不知道如何确保传递给脚本的参数是否为数字。
我只想这样做:
test *isnumber* $1 && VAR=$1 || echo "need a number"
有什么帮助吗?
我只是不知道如何确保传递给脚本的参数是否为数字。
我只想这样做:
test *isnumber* $1 && VAR=$1 || echo "need a number"
有什么帮助吗?
当前回答
几乎是你想要的语法。只需要一个函数编号:
#!/usr/bin/bash
isnumber(){
num=$1
if [ -z "${num##*[!0-9]*}" ];
then return 1
else
return 0
fi
}
$(isnumber $1) && VAR=$1 || echo "need a number";
echo "VAR is $VAR"
测试:
$ ./isnumtest 10
VAR is 10
$ ./isnumtest abc10
need a number
VAR is
其他回答
因为我最近不得不修改这个,并且最喜欢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; }
我尝试了超锯片的配方,因为它对我来说似乎是最实用的,但没能奏效。最后,我设计了另一种方法,与其他参数替换方法一样,这次使用正则表达式替换:
[[ "${var//*([[:digit:]])}" ]]; && echo "$var is not numeric" || echo "$var is numeric"
它删除$var中的每一个:digit:class字符,并检查是否剩下一个空字符串,这意味着原始字符串只有数字。
我喜欢这款车的地方是它的占地面积小,灵活性强。在这种形式中,它只适用于非分隔的、以10为基数的整数,当然您可以使用模式匹配来满足其他需要。
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
对于我的问题,我只需要确保用户不会意外地输入一些文本,因此我试图保持它简单易读
isNumber() {
(( $1 )) 2>/dev/null
}
根据手册页,这很符合我的要求
如果表达式的值为非零,则返回状态为0
为了防止“可能是数字”的字符串出现令人讨厌的错误消息,我忽略了错误输出
$ (( 2s ))
bash: ((: 2s: value too great for base (error token is "2s")
我找到了一个很短的版本:
function isnum()
{
return `echo "$1" | awk -F"\n" '{print ($0 != $0+0)}'`
}