I just can't figure out how do I make sure an argument passed to my script is a number or not.
All I want to do is something like this:
test *isnumber* $1 && VAR=$1 || echo "need a number"
Any help?
I just can't figure out how do I make sure an argument passed to my script is a number or not.
All I want to do is something like this:
test *isnumber* $1 && VAR=$1 || echo "need a number"
Any help?
I was looking at the answers and... realized that nobody thought about FLOAT numbers (with dot)!
Using grep is great too.
-E means extended regexp
-q means quiet (doesn't echo)
-qE is the combination of both.
To test directly in the command line:
Using in a bash script:
To match JUST integers, use this:
Can't comment yet so I'll add my own answer, which is an extension to glenn jackman's answer using bash pattern matching.
My original need was to identify numbers and distinguish integers and floats. The function definitions deducted to:
I used unit testing (with shUnit2) to validate my patterns worked as intended:
Notes: The isFloat pattern can be modified to be more tolerant about decimal point (
@(.,)
) and the E symbol (@(Ee)
). My unit tests test only values that are either integer or float, but not any invalid input.${i//[0-9]}
replaces any digit in the value of$i
with an empty string, seeman -P 'less +/parameter\/' bash
.-z
checks if resulting string has zero length.if you also want to exclude the case when
$i
is empty, you could use one of these constructions:I tried ultrasawblade's recipe as it seemed the most practical to me, and couldn't make it work. In the end i devised another way though, based as others in parameter substitution, this time with regex replacement:
It removes every :digit: class character in $var and checks if we are left with an empty string, meaning that the original was only numbers.
What i like about this one is its small footprint and flexibility. In this form it only works for non-delimited, base 10 integers, though surely you can use pattern matching to suit it to other needs.
Remove the
-\?
in grep matching pattern if you don't accept negative integer.http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_04_03.html
You can also use bash's character classes.
Numerics will include space, the decimal point, and "e" or "E" for floating point.
But, if you specify a C-style hex number, i.e. "0xffff" or "0XFFFF", [[:digit:]] returns true. A bit of a trap here, bash allows you do to something like "0xAZ00" and still count it as a digit (isn't this from some weird quirk of GCC compilers that let you use 0x notation for bases other than 16???)
You might want to test for "0x" or "0X" before testing if it's a numeric if your input is completely untrusted, unless you want to accept hex numbers. That would be accomplished by: