我只是不知道如何确保传递给脚本的参数是否为数字。

我只想这样做:

test *isnumber* $1 && VAR=$1 || echo "need a number"

有什么帮助吗?


当前回答

我找到了一个很短的版本:

function isnum()
{
    return `echo "$1" | awk -F"\n" '{print ($0 != $0+0)}'`
}

其他回答

老问题,但我只是想坚持我的解决方案。这一个不需要任何奇怪的外壳技巧,也不需要依赖于永远不存在的东西。

if [ -n "$(printf '%s\n' "$var" | sed 's/[0-9]//g')" ]; then
    echo 'is not numeric'
else
    echo 'is numeric'
fi

基本上,它只是从输入中删除所有数字,如果你留下一个非零长度的字符串,那么它就不是一个数字。

这将测试数字是否为非负整数。它是独立于外壳的(即没有bashms),只使用外壳内置:

[ ! -z "${num##*[!0-9]*}" ] && echo "is a number" || echo "is not a number";

此答案的先前版本提出:

[ -z "${num##[0-9]*}" ] && echo "is a number" || echo "is not a number";

但这是不正确的,因为它接受任何以数字开头的字符串,正如jilles所建议的那样。

我对在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
}

将“%f”更改为所需的任何特定格式。

以下是我编写的脚本,用于与Nagios的脚本集成,到目前为止运行正常

#!/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

EG:

# 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

@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