测试一个变量是否为整数

25

我想测试一下我的变量$var是否为整数。请问如何实现?

7个回答

25
只要您使用的是bash版本 >=3,您就可以使用正则表达式:
[[ $a =~ ^-?[0-9]+$ ]] && echo integer

虽然这个bash FAQ提到在各种bash 3.x中的bash正则表达式实现中存在不一致性(是否应该引用正则表达式),但我认为在此情况下,任何版本都不需要引用任何字符,所以我们很安全。至少在以下版本中对我有效:

  • 3.00.15(1)-release (x86_64-redhat-linux-gnu)
  • 3.2.48(1)-release (x86_64-apple-darwin12)
  • 4.2.25(1)-release (x86_64-pc-linux-gnu)
$ a=""
$ [[ $a =~ ^-?[0-9]+$ ]] && echo integer
$ a=" "
$ [[ $a =~ ^-?[0-9]+$ ]] && echo integer
$ a="a"
$ [[ $a =~ ^-?[0-9]+$ ]] && echo integer
$ a='hello world!'
$ [[ $a =~ ^-?[0-9]+$ ]] && echo integer
$ a='hello world 42!'
$ [[ $a =~ ^-?[0-9]+$ ]] && echo integer
$ a="42"
$ [[ $a =~ ^-?[0-9]+$ ]] && echo integer
整数
$ a="42.1"
$ [[ $a =~ ^-?[0-9]+$ ]] && echo integer
$ a="-42"
$ [[ $a =~ ^-?[0-9]+$ ]] && echo integer
整数
$ a="two"
$ [[ $a =~ ^-?[0-9]+$ ]] && echo integer

8
一个不太正规但是可移植的解决方案是使用 test 命令的 -eq(整数相等)运算符将值与自身进行比较,并丢弃任何结果错误信息。
is_int () { test "$@" -eq "$@" 2> /dev/null; }

for input in "0.3" "abc" "3"; do
    if is_int "$input"; then
        echo "Integer: $input"
    else
        echo "Not an integer: $input"
    fi
done

从我看来,没有必要将fd2重定向到“/dev/null”。而且这在空字符串上工作得很好。它也符合POSIX标准。非常干净,但有些技巧。 - kvantour

6
我需要一个只针对正整数返回true的东西(并对空字符串失败)。我选择了这个: test -n "$1" -a "$1" -ge 0 2>/dev/null 因为如果输入(到-ge)不能解析为整数,测试会打印错误(并返回2),所以有2>/dev/null
我希望它可以更短,但“test”似乎没有“安静”选项,并且将空字符串视为有效整数(零)。

2
shopt -s extglob
case "$var" in
 +([0-9]) ) echo "integer";
esac

1
你可以这样做:
shopt -s extglob

if [ -z "${varname##+([0-9])}" ]
then
  echo "${varname} is an integer"
else
  echo "${varname} is not an integer"
fi

##贪婪地从“varname”返回的值中删除正则表达式,因此如果变量是整数,则为真;否则为假。

它与顶部答案(使用“$foo!= [!0-9] ”)具有相同的弱点,即如果$varname为空,则返回true。我不知道是否有效。如果无效,请将测试更改为:

if [ -n "$varname" ] && [ -z "${varname##[0-9]}" ]

刚刚注意到上面有一个错误,其中说1a1是一个整数:P...等一下 - Svend Hansen
我无法理解“文件名扩展”方式编写“一个或多个模式xxx”的方法。因此,当我编写[0-9]*时,它匹配一个整数后跟任何字符,因此“1a1”,“1a”或“1blah”都匹配...使用FAQ中链接的测试可以进行如下操作:if [[ "$varname" == +([0-9]) ]],但“[[”不是标准BASH,必须使用“正确”的正则表达式扩展而不是文件扩展。有人知道如何使我的解决方案工作吗? :P - Svend Hansen
ghostdog74的解决方案给了我答案。添加shopt -s extglob,我猜是启用了所需的模式语法 :) - Svend Hansen

1

echo your_variable_here | grep "^-\?[0-9]*$" 如果变量是整数,则返回该变量,否则不返回任何内容。


2
实际上,如果它是整数,它也会将变量打印到stdout。你真正想要的是grep -q,它不会打印到stdout,只有在匹配时才会以0或非0退出。 - Adam Rosenfield

0
您可以执行一个 *2 /2 操作,该操作检查值是否为数字且为整数。 如果不是数字,则操作返回0
echo "Try with 10"

var=10
var1=`echo $((($var*2)/2))`

if [ "$var" == "$var1" ]; then
  echo '$var integer'
else
  echo '$var not integer'
fi

echo "Try with string"

var=string
var1=`echo $((($var*2)/2))`

if [ "$var" == "$var1" ]; then
  echo '$var integer'
else
  echo '$var not integer'
fi

确切地复制了 https://dev59.com/p3E95IYBdhLWcg3wrPwn#21884506 - Paresh Mayani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接