我只是不知道如何确保传递给脚本的参数是否为数字。
我只想这样做:
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为基数的整数,当然您可以使用模式匹配来满足其他需要。
跟进2013年10月David W的回答,如果使用expr,这可能会更好
test_var=`expr $am_i_numeric \* 0` >/dev/null 2>&1
if [ "$test_var" = "" ]
then
......
如果是数字,则乘以1将得到相同的值(包括负数)。否则,您将得到空值,您可以进行测试
我使用printf作为其他提到的答案,如果您提供格式字符串“%f”或“%I”,printf将为您进行检查。比重新发明支票更容易,语法简单简短,printf无处不在。所以在我看来,这是一个不错的选择——你也可以使用下面的想法来检查一系列的东西,它不仅对检查数字有用。
declare -r CHECK_FLOAT="%f"
declare -r CHECK_INTEGER="%i"
## <arg 1> Number - Number to check
## <arg 2> String - Number type to check
## <arg 3> 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
}
>$var=45
>$(($(check_number$var“${check_INTEGER}”“错误:找到$var-需要一个整数。”))&{echo“$var+5”|bc;}
这将测试数字是否为非负整数。它是独立于外壳的(即没有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所建议的那样。
这可以通过使用grep查看所讨论的变量是否与扩展正则表达式匹配来实现。
测试整数1120:
yournumber=1120
if echo "$yournumber" | grep -qE '^[0-9]+$'; then
echo "Valid number."
else
echo "Error: not a number."
fi
输出:有效数字。
测试非整数1120a:
yournumber=1120a
if echo "$yournumber" | grep -qE '^[0-9]+$'; then
echo "Valid number."
else
echo "Error: not a number."
fi
输出:错误:不是数字。
解释
grep和-E开关允许我们使用扩展正则表达式“^[0-9]+$”。此正则表达式表示变量从^开始到$结束只应[]包含0-9 0到9的数字,并且至少应有+1个字符。grep,-q quiet开关关闭任何输出,无论它是否找到任何内容。if检查grep的退出状态。退出状态0表示成功,大于0表示错误。如果grep命令找到匹配项,则其退出状态为0,如果没有找到,则为1;
因此,在if测试中,我们将所有这些放在一起,返回变量$yournumber并|将其通过管道传递给grep,grep使用-q开关与-E扩展正则表达式“^[0-9]+$”表达式匹配。如果grep成功找到匹配项,则grep的退出状态为0,如果没有找到匹配项则为1。如果匹配成功,我们将返回“有效数字”。如果匹配失败,我们将回显“错误:不是数字”。
对于浮球或双打
我们可以将正则表达式从“^[0-9]+$”更改为“^[0-10]*\”。?[0-9]+$'表示浮点或双精度。
测试浮子1120.01:
yournumber=1120.01
if echo "$yournumber" | grep -qE '^[0-9]*\.?[0-9]+$'; then
echo "Valid number."
else
echo "Error: not a number."
fi
输出:有效数字。
测试浮子11.20.01:
yournumber=11.20.01
if echo "$yournumber" | grep -qE '^[0-9]*\.?[0-9]+$'; then
echo "Valid number."
else
echo "Error: not a number."
fi
输出:错误:不是数字。
对于否定词
要允许负整数,只需将正则表达式从“^[0-9]+$”更改为“^\-?[0-9]+$'.
要允许负浮点数或双精度,只需将正则表达式从“^[0-9]*\”更改。?[0-9]+$'到'^\-?[0-9]*\.?[0-9]+$'.