Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
检查变量是否为UNIX shell中的数字_Unix_Shell - Fatal编程技术网

检查变量是否为UNIX 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

如何在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]+$'
    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
}