How to check whether a string is number or not

Hi ,
I am facing a problem .. which looks simple... but took 2 days of mine.. even now it is not solved completely..

I have one variable..., want to know whether that variable contains number... canbe +ve or -ve ...

Values
+35 --- number
-43 --- number
45A -- non number
34+45 -- non number

please help me
Shihab

Look at the solution given in this post

Let me knows if it falters for any condition.

Vino

Another solution vaild only for integers, decimals not allowed :smiley:

#!/bin/ksh
echo "Enter val : \c"
read num
expr $num + 1 2> /dev/null
if [ $? = 0 ]
then
echo "Val was numeric"
else
echo "Val was non-numeric"
fi

rishi :o

Hi rishi ,
It won't work if the number is like +567
example expr +567 + 1 .. will fail

Regards
Shihab

if u r using tcl or perl there is finction calles isnumber

if [ isnumber $a ] {
}
:cool:

A small edit Shihab,

#!/bin/ksh
echo "Enter val : \c"
read num
expr "$num + 1" 2> /dev/null
if [ $? = 0 ]
then
echo "Val was numeric"
else
echo "Val was non-numeric"
fi

Note the double qutoes around the expression.

Rishi

how abt this,

[[ `echo $num | sed 's/^[-+0-9][0-9]*//' | wc -c` -eq 1 ]] && echo "itz number" && exit 0
echo "itz not number"

not thoroughly tested
plz let me know, if it faints somewhere

The problem can easily be solved by considering what a "number" is actually and since this is a good opportunity to show how to develop regular expressions I will explain that in greater detail:

1st Try
The only characters allowed should be 0-9. This covers for "123", but not for "123.0". Hence

2nd Try
Only 0-9 are allowed, save for exactly 1 character, which may be a fullstop. This definition covers "123" and "456.78", leaves out (quite correctly) "123.456.789", but doesn't cover "-123.0" or "+123.0". Hence

3rd Try
In addition to 2nd Try the first character may be "+" or "-" optionally. This covers every number and leaves out any non-number, so this solution is perfect.

We develop a simple sed-statement from there, by consecutively throwing out all "allowed" chars and look, if something remains. If something remains it is non-numeric, if not, then it is numeric:

if [ -n "$( print - "$VarInQuestion"           |\
            sed 's/^[+-]//;s/[0-9]//g;s/\.//'   \
          )" ] ; then
     print - "$VarInQuestion is non-numeric"
else
     print - "$VarInQuestion is numeric"
fi

Here is the sed-statement in detail:

s/^[+-]// - see 3rd try, we chop off leading +/- signs
s/[0-9]//g - see 1st try, we throw out all numerical digits
s/\.// - see 2nd try, we throw out one possible decimal point

bakunin

Hi All..
Thanks a lot....
It is working fine now...
Shihab

$
$ x=1; if [ "`expr $x - $x 2>/dev/null`" == "0" ]; then echo is number; else echo not number; fi
is number
$ x=-1; if [ "`expr $x - $x 2>/dev/null`" == "0" ]; then echo is number; else echo not number; fi
is number
$ x=a; if [ "`expr $x - $x 2>/dev/null`" == "0" ]; then echo is number; else echo not number; fi
not number
$ x=1a; if [ "`expr $x - $x 2>/dev/null`" == "0" ]; then echo is number; else echo not number; fi
not number
$

This solution is better as it works for decimals as well:

$ x=a; printf "%g" $x >/dev/null 2>&1; if [ $? -eq 0 ]; then echo is number; else echo not number; fi
not number
$ x=9a; printf "%g" $x >/dev/null 2>&1; if [ $? -eq 0 ]; then echo is number; else echo not number; fi
not number
$ x=9; printf "%g" $x >/dev/null 2>&1; if [ $? -eq 0 ]; then echo is number; else echo not number; fi
is number
$ x=9.1; printf "%g" $x >/dev/null 2>&1; if [ $? -eq 0 ]; then echo is number; else echo not number; fi
is number
$ x=-9.1; printf "%g" $x >/dev/null 2>&1; if [ $? -eq 0 ]; then echo is number; else echo not number; fi
is number
$ x=-9; printf "%g" $x >/dev/null 2>&1; if [ $? -eq 0 ]; then echo is number; else echo not number; fi
is number
awk '$1+0==$1' a.txt

try this:

function validatenumber
{
number="$1"
if [ -z $number ];then
echo "not  something" > &2;return 1
fi

if [ "${number%${number#?}} = "-" ]; then
testvalue="${number#?}"
fi

if [ "${number%${number#?}} = "+" ]; then
testvalue="${number#?}"
fi

nodigits="$(echo $testvalue | sed 's/[[:digit:]]]//g')"
if [ ! -z $nodigits ]; then
echo "Invalid Number" > &2
return 1
fi

return 0
}

if validatenumber "$1"; then
echo "No is a valid integer"
fi

cheers,
Devaraj Takhellambam