我只是不知道如何确保传递给脚本的参数是否为数字。
我只想这样做:
test *isnumber* $1 && VAR=$1 || echo "need a number"
有什么帮助吗?
我只是不知道如何确保传递给脚本的参数是否为数字。
我只想这样做:
test *isnumber* $1 && VAR=$1 || echo "need a number"
有什么帮助吗?
当前回答
现在还不能评论,所以我将添加我自己的答案,这是使用bash模式匹配对glenn jackman答案的扩展。
我最初的需要是识别数字,区分整数和浮点数。函数定义被推导为:
function isInteger() {
[[ ${1} == ?(-)+([0-9]) ]]
}
function isFloat() {
[[ ${1} == ?(-)@(+([0-9]).*([0-9])|*([0-9]).+([0-9]))?(E?(-|+)+([0-9])) ]]
}
我使用单元测试(使用shUnit2)来验证我的模式是否按预期工作:
oneTimeSetUp() {
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"
}
testIsIntegerIsFloat() {
local value
for value in ${int_values}
do
assertTrue "${value} should be tested as integer" "isInteger ${value}"
assertFalse "${value} should not be tested as float" "isFloat ${value}"
done
for value in ${float_values}
do
assertTrue "${value} should be tested as float" "isFloat ${value}"
assertFalse "${value} should not be tested as integer" "isInteger ${value}"
done
}
注意:isFloat模式可以修改为对小数点(@(.,))和E符号(@(Ee))更宽容。我的单元测试只测试整数或浮点值,但不测试任何无效输入。
其他回答
我使用expr。如果尝试将零添加到非数值,则返回非零:
if expr -- "$number" + 0 > /dev/null 2>&1
then
echo "$number is a number"
else
echo "$number isn't a number"
fi
如果需要非整数,可以使用bc,但我不认为bc有完全相同的行为。将零添加到非数字会得到零,它也会返回值零。也许你可以把bc和expr结合起来。使用bc将零添加到$number。如果答案为0,则尝试expr验证$number不为零。
我尝试了超锯片的配方,因为它对我来说似乎是最实用的,但没能奏效。最后,我设计了另一种方法,与其他参数替换方法一样,这次使用正则表达式替换:
[[ "${var//*([[:digit:]])}" ]]; && echo "$var is not numeric" || echo "$var is numeric"
它删除$var中的每一个:digit:class字符,并检查是否剩下一个空字符串,这意味着原始字符串只有数字。
我喜欢这款车的地方是它的占地面积小,灵活性强。在这种形式中,它只适用于非分隔的、以10为基数的整数,当然您可以使用模式匹配来满足其他需要。
以下解决方案也可以用于Bourne等基本shell,而不需要正则表达式。基本上,任何使用非数字的数值求值操作都会导致错误,在shell中,该错误将被隐式视为false:
"$var" -eq "$var"
如:
#!/bin/bash
var=a
if [ -n "$var" ] && [ "$var" -eq "$var" ] 2>/dev/null; then
echo number
else
echo not a number
fi
你也可以测试$?更明确的操作返回代码:
[ -n "$var" ] && [ "$var" -eq "$var" ] 2>/dev/null
if [ $? -ne 0 ]; then
echo $var is not number
fi
标准错误的重定向是为了隐藏bash打印出的“预期整数表达式”消息,以防我们没有数字。
CAVETS(感谢以下评论):
带小数点的数字不被识别为有效的“数字”使用[[]]而不是[]将始终计算为true大多数非Bash shell始终将此表达式求值为trueBash中的行为没有记录,因此可能会在没有警告的情况下发生变化如果值在数字后面包含空格(例如“1 a”),则会产生错误,如bash:[[:1 a:表达式中的语法错误(错误标记为“a”)如果该值与var名称相同(例如i=“i”),则会产生错误,如bash:[[:i:expression递归级别超出(错误标记为“i”
printf '%b' "-123\nABC" | tr '[:space:]' '_' | grep -q '^-\?[[:digit:]]\+$' && echo "Integer." || echo "NOT integer."
删除-\?在grep匹配模式中,如果不接受负整数。
一种简单的方法是检查它是否包含非数字字符。您可以将所有数字字符替换为空,并检查长度。如果有长度,那不是数字。
if [[ ! -n ${input//[0-9]/} ]]; then
echo "Input Is A Number"
fi