Testing if a variable is an integer [duplicate]
I would like to test if my variable $var
is actually an integer or not. How can I please do that?
As long as you're using bash version >=3 you can use a regular expression:
[[ $a =~ ^-?[0-9]+$ ]] && echo integer
While this bash FAQ mentions inconsistencies in the bash regex implementation in various bash 3.x (should the regex be quoted or not), I think in this case, there are no characters that need quoting in any version, so we are safe. At least it works for me in:
- 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 integer $ a="42.1" $ [[ $a =~ ^-?[0-9]+$ ]] && echo integer $ a="-42" $ [[ $a =~ ^-?[0-9]+$ ]] && echo integer integer $ a="two" $ [[ $a =~ ^-?[0-9]+$ ]] && echo integer
A hackish-but-portable solution is to compare the value with itself using test
's -eq
(integer equality) operator and throw away any resulting error message:
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
I was needing something that would return true only for positive integers (and fail for the empty string). I settled on this:
test -n "$1" -a "$1" -ge 0 2>/dev/null
the 2>/dev/null
is there because test prints an error (and returns 2) if an input (to -ge) doesn't parse as an integer
I wish it could be shorter, but "test" doesn't seem to have a "quiet" option and treats "" as a valid integer (zero).
shopt -s extglob
case "$var" in
+([0-9]) ) echo "integer";
esac
echo your_variable_here | grep "^-\?[0-9]*$"
will return the variable if it is an integer and return nothing otherwise.
You can do this:
shopt -s extglob
if [ -z "${varname##+([0-9])}" ]
then
echo "${varname} is an integer"
else
echo "${varname} is not an integer"
fi
The ## greedily removes the regular expression from the value returned by "varname", so if the var is an integer it is true, false if not.
It has the same weakness as the top answer (using "$foo != [!0-9]"), that if $varname is empty it returns true. I don't know if that's valid. If not just change the test to:
if [ -n "$varname" ] && [ -z "${varname##[0-9]}" ]
You can perform a *2 /2 operation that check both if value is numeric and is integer. The operation returns 0 if not numeric
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
精彩评论