我只是不知道如何确保传递给脚本的参数是否为数字。
我只想这样做:
test *isnumber* $1 && VAR=$1 || echo "need a number"
有什么帮助吗?
我只是不知道如何确保传递给脚本的参数是否为数字。
我只想这样做:
test *isnumber* $1 && VAR=$1 || echo "need a number"
有什么帮助吗?
当前回答
@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或其他语言中的许多程序都会以这种方式导出浮点数),这一行的一个有用补充如下:
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
注意:我们可以列出十进制和科学记数法的语法要求,其中之一是允许逗号作为基点,以及“.”。然后我们可以断言,这样的基点必须只有一个。[Ee]浮点数中可以有两个+/-符号。我从奥卢的工作中学到了更多的规则,并测试了“”-“”-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
其他回答
我尝试了超锯片的配方,因为它对我来说似乎是最实用的,但没能奏效。最后,我设计了另一种方法,与其他参数替换方法一样,这次使用正则表达式替换:
[[ "${var//*([[:digit:]])}" ]]; && echo "$var is not numeric" || echo "$var is numeric"
它删除$var中的每一个:digit:class字符,并检查是否剩下一个空字符串,这意味着原始字符串只有数字。
我喜欢这款车的地方是它的占地面积小,灵活性强。在这种形式中,它只适用于非分隔的、以10为基数的整数,当然您可以使用模式匹配来满足其他需要。
Stack弹出了一条消息,问我是否真的想在回答30+后回答?但当然!!!使用bash新功能,如下所示:(在评论之后我做了更改)
函数isInt(){([[$1-eq$(($1+0))]]2>/dev/null&&[[$1!=“”]]&&echo 1)|| echo“”}
function isInt() {
([[ $1 =~ ^[-+0-9]+$ ]] && [[ $1 -eq $(( $1 + 0 )) ]] 2>/dev/null && [[ $1 != '' ]] && echo 1) || echo ''
}
支架:
===============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).
只有当与[[$(isInt<arg>)]]中的过程替换结合使用时,才能从函数中获得真/假,因为bash中没有逻辑类型,也没有函数的返回值。
当测试表达式的结果为“错误”时,我使用大写,反之亦然!
通过“算术”,我的意思是bash可以像以下表达式那样进行数学运算:$x=$(($y+34))。
当在数学表达式中,参数的行为与预期一致时,我使用“算术/无算术”;当参数与预期行为相比表现不佳时,我则使用“无算术”。
正如你所看到的,只有10和11是有问题的!
完美的
PS:请注意,最流行的答案在情况9中失败!
我喜欢阿尔贝托·扎卡尼的回答。
if [ "$var" -eq "$var" ] 2>/dev/null; then
重要的先决条件:-未生成子壳-未调用RE解析器-大多数shell应用程序不使用实数
但是,如果$var是复杂的(例如,关联数组访问),并且如果数字是非负整数(大多数用例),那么这可能更有效?
if [ "$var" -ge 0 ] 2> /dev/null; then ..
对于我的问题,我只需要确保用户不会意外地输入一些文本,因此我试图保持它简单易读
isNumber() {
(( $1 )) 2>/dev/null
}
根据手册页,这很符合我的要求
如果表达式的值为非零,则返回状态为0
为了防止“可能是数字”的字符串出现令人讨厌的错误消息,我忽略了错误输出
$ (( 2s ))
bash: ((: 2s: value too great for base (error token is "2s")
一种简单的方法是检查它是否包含非数字字符。您可以将所有数字字符替换为空,并检查长度。如果有长度,那不是数字。
if [[ ! -n ${input//[0-9]/} ]]; then
echo "Input Is A Number"
fi