检查变量是否为UNIX shell中的数字
如何在UNIX shell中检查变量是否为数字或包含数字?shell变量没有类型,因此最简单的方法是使用返回类型检查变量是否为UNIX shell中的数字,unix,shell,Unix,Shell,如何在UNIX shell中检查变量是否为数字或包含数字?shell变量没有类型,因此最简单的方法是使用返回类型test命令: if [ $var -eq $var 2> /dev/null ]; then ... (或者使用regexp解析它)在启用extglob选项的ksh93或bash中: if [[ $var == +([0-9]) ]]; then ... 这可以使用正则表达式进行检查 ### echo $var|egrep '^[0-9]+$' i
test
命令:
if [ $var -eq $var 2> /dev/null ]; then ...
(或者使用regexp解析它)在启用extglob选项的ksh93或bash中:
if [[ $var == +([0-9]) ]]; then ...
这可以使用正则表达式进行检查
###
echo $var|egrep '^[0-9]+$'
if [ $? -eq 0 ]; then
echo "$var is a number"
else
echo "$var is not a number"
fi
这是一个只使用裸壳中可用功能的版本(即它在
sh
中工作),并且比使用grep
少一个过程:
if expr "$var" : '[0-9][0-9]*$'>/dev/null; then
echo yes
else
echo no
fi
这检查
$var
是否仅代表一个整数;根据口味调整regexp,注意,expr
regexp参数隐式地锚定在开头。没有分叉,就没有管道。纯POSIX外壳:
case $var in
(*[!0-9]*|'') echo not a number;;
(*) echo a number;;
esac
(假设数字:=一组数字)。如果您希望允许有符号的数字同时具有单个前导的-
或+
,请按如下方式去除可选符号:
case ${var#[-+]} in
(*[!0-9]*|'') echo not a number;;
(*) echo a number;;
esac
数字的
ng
我对shell编程有点生疏,所以我试图找出最简单易读的 它只会检查var是否大于或等于0 我认为这是选择参数的好方法。。。可能永远都不是…:
if [ $var -ge 0 2>/dev/null ] ; then ...
实际上,如果var是多行的,这就不起作用了
即
特别是如果var来自一个文件:
var=`cat var.txt`
这是最简单的:
if [ "$var" -eq "$var" ] 2> /dev/null
then echo yes
else echo no
fi
您可以使用简单的测试命令来实现这一点
$ test ab -eq 1 >/dev/null 2>&1
$ echo $?
2
$ test 21 -eq 1 >/dev/null 2>&1
$ echo $?
1
$ test 1 -eq 1 >/dev/null 2>&1
$ echo $?
0
因此,如果退出状态为0或1,则它是一个整数,但如果退出状态为2,则它不是一个数字。以下是不带任何正则表达式的测试(tcsh代码): 创建文件检查编号: #! /usr/bin/env tcsh
if ( "$*" == "0" ) then
exit 0 # number
else
((echo "$*" | bc) > /tmp/tmp.txt) >& /dev/null
set tmp = `cat /tmp/tmp.txt`
rm -f /tmp/tmp/txt
if ( "$tmp" == "" || $tmp == 0 ) then
exit 1 # not a number
else
exit 0 # number
endif
endif
跑
chmod +x checknumber
使用
您将得到errorlevel($?)的结果
您可以轻松地对其进行优化。INTEGER
测试(var=2等):
2 is an integer
-2 is an integer
2.5 is not an integer
2b is not an integer
2 is a number
-2 is a number
-2.6 is a number
-2.c6 is not a number
2. is not a number
2.0 is a number
数
测试(var=2等):
2 is an integer
-2 is an integer
2.5 is not an integer
2b is not an integer
2 is a number
-2 is a number
-2.6 is a number
-2.c6 is not a number
2. is not a number
2.0 is a number
从命令行获取值并显示输入是否为十进制/非十进制和数字:
NUMBER=$1
IsDecimal=`echo "$NUMBER" | grep "\."`
if [ -n "$IsDecimal" ]
then
echo "$NUMBER is Decimal"
var1=`echo "$NUMBER" | cut -d"." -f1`
var2=`echo "$NUMBER" | cut -d"." -f2`
Digit1=`echo "$var1" | egrep '^-[0-9]+$'`
Digit2=`echo "$var1" | egrep '^[0-9]+$'`
Digit3=`echo "$var2" | egrep '^[0-9]+$'`
if [ -n "$Digit1" ] && [ -n "$Digit3" ]
then
echo "$NUMBER is a number"
elif [ -n "$Digit2" ] && [ -n "$Digit3" ]
then
echo "$NUMBER is a number"
else
echo "$NUMBER is not a number"
fi
else
echo "$NUMBER is not Decimal"
Digit1=`echo "$NUMBER" | egrep '^-[0-9]+$'`
Digit2=`echo "$NUMBER" | egrep '^[0-9]+$'`
if [ -n "$Digit1" ] || [ -n "$Digit2" ]; then
echo "$NUMBER is a number"
else
echo "$NUMBER is not a number"
fi
fi
我不知道这是否正确,这检查它是否是整数(不是数字)。如果问题出现在描述中(“包含”),我会将regexp改为“[0-9]”,以解决问题;如果问题出现在标题中(“is”),我会将regexp改为处理非整数。对于可以在shell中完成的简单操作,叉管和鹭鸶浪费了多少个循环?希望这在一个紧密的循环中不需要…@Jens:你是对的,这个答案不如不产生子流程的答案有效,尽管大多数情况下这不会产生任何实际影响。“我赞成你更好的答案。”阿达姆罗森菲尔德谢谢,这是面对批评时的一种高尚姿态。世界需要更多的这种态度。不要忘记负数。假设我们只讨论整数(整数),而不是浮点数(实数)——即,与test(1)的数字运算符(-eq等)一起工作的数字,我们可以在这里调整regex方法以包括负整数,如:
echo$var | egrep-q'^-*[:digit:]+$&&echo是num | | echo不是num
(当然,仅适用于10进制)它甚至适用于过度否定但合法的数字如---23。标题询问变量是否是一个数字,描述询问它是否包含一个数字。你想要哪一个?而且,当你说数字D o你是指整数还是应该处理小数?你考虑3.1415个数吗?你能加一个你的解答的解释吗?@史蒂文韦斯特布rook:这将从$a中删除数字,并计算剩余的数字。如果有剩余,则它不是一个仅由数字组成的字符串(“非数字”)。不处理负数(例如,-123,--123)。不幸的是,使用这种fork-heavy方法添加对负数的支持意味着在管道中添加另一个tr-d-
。您可以将tr(1)表达式更改为“[[:digit:]”,以捕获负数(或使用[:xdigit:]表示基数为16的数字),但这会产生类似123-54的假阳性(认为这是一个有效的数字)。如果var为空,这将给出一个假阳性。可能:如果[-n“$var”-a$var-eq$var 2>/dev/null];那么echo是num;否则echo不是num;fi
也很好,这适用于基本的bourne/korn shell(不需要Bashism)。一个缺点:在测试中(1)我使用了(FreeBSD 9,Fedora 20),当var被过度求反(例如--234)时,这将失败,尽管算术运算可以工作(例如,echo$(-234*2))
)。要处理负数(即使是过度但合法地求反,如--234),如果[[$var==+(*[:digit:]]),则将其调整为;然后echo是num;否则echo不是num;fi
。很好地处理空的或未设置的var
以及多字var
(例如,“brown cow”)。使用[:xdigit:::
字符类作为基数16 num。注意:与区域设置无关的字符类(例如[:digit:]似乎无法使用ksh。这会很快变得复杂。请尝试使用“brown cow”、“123Q”、“0xAbc”、“123Q”、“123”、“-123”、“-345”进行测试。bash/ksh中“扩展正则表达式”的各种实现都会增加复杂性。对基本posix shell缺乏可移植性的问题,请投反对票(更多的是对这个方法的否决票,而不是达伦的答案,因为他非常直截了当地接受了这个限制)。你们能帮我理解一下吗:#x=200#[+([0-9])==x]&&echo number | echo not number>not a number#[$x=+([0-9])]&&echo number | | echo not number>numberw这是怎么添加的?这个确切的方法是在2008年Adam的回复中。(-1)不支持否定整数(-123,--123)。对于否定数字:expr“$var”:“-*[0-9][0-9]*$”&&echo num | echo not num
为可移植性投票(例如,无bashisms);额外的fork有轻微的缺点。不处理负数(例如,-123,--123)。@Juan:这就是我明确说明这个假设的原因。很公平。我只是想在所有的解决方案上都说清楚。在som上
checknumber -3.45
if echo "$var" | egrep -q '^\-?[0-9]+$'; then
echo "$var is an integer"
else
echo "$var is not an integer"
fi
2 is an integer
-2 is an integer
2.5 is not an integer
2b is not an integer
if echo "$var" | egrep -q '^\-?[0-9]*\.?[0-9]+$'; then
echo "$var is a number"
else
echo "$var is not a number"
fi
2 is a number
-2 is a number
-2.6 is a number
-2.c6 is not a number
2. is not a number
2.0 is a number
NUMBER=$1
IsDecimal=`echo "$NUMBER" | grep "\."`
if [ -n "$IsDecimal" ]
then
echo "$NUMBER is Decimal"
var1=`echo "$NUMBER" | cut -d"." -f1`
var2=`echo "$NUMBER" | cut -d"." -f2`
Digit1=`echo "$var1" | egrep '^-[0-9]+$'`
Digit2=`echo "$var1" | egrep '^[0-9]+$'`
Digit3=`echo "$var2" | egrep '^[0-9]+$'`
if [ -n "$Digit1" ] && [ -n "$Digit3" ]
then
echo "$NUMBER is a number"
elif [ -n "$Digit2" ] && [ -n "$Digit3" ]
then
echo "$NUMBER is a number"
else
echo "$NUMBER is not a number"
fi
else
echo "$NUMBER is not Decimal"
Digit1=`echo "$NUMBER" | egrep '^-[0-9]+$'`
Digit2=`echo "$NUMBER" | egrep '^[0-9]+$'`
if [ -n "$Digit1" ] || [ -n "$Digit2" ]; then
echo "$NUMBER is a number"
else
echo "$NUMBER is not a number"
fi
fi
( test ! -z "$num" && test "$num" -eq "$num" 2> /dev/null ) && {
# $num is a number
}