[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::digital_unix

Title:DIGITAL UNIX(FORMERLY KNOWN AS DEC OSF/1)
Notice:Welcome to the Digital UNIX Conference
Moderator:SMURF::DENHAM
Created:Thu Mar 16 1995
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:10068
Total number of notes:35879

9736.0. "numeric Bourne shell variable - how to test?" by GIDDAY::STRAUSS (talking through my binoculars) Wed May 07 1997 01:00

    Here's a Bourne shell puzzle - how to test whether or not a shell
    variable is numeric?
    
    This script works ...
    
    	#!/bin/sh
    	# test $1 to see if it's numeric
    	if eval "echo $1 | grep -s -v '[^0123456789]'"
    	then
    	        echo $1 is a number
    	else
    	        echo $1 is not a number
    	fi
    
    ... but it seems kludgy, and the "eval" echoes the value to stdout,
    which I don't necessarily want.
    
    	case `echo $1 | grep -s -v '[^0123456789]'` in
    	        "")     echo $1 not numeric;;
    	        *)      echo $1 numeric;;
    	esac
    
    ... also seems kludgy.
    
    I've had similar (lack of) success with expr.
    
    A character class expression like [[:digit:]] seemed promising, but
    that depends on LC_CTYPE which in turn depends on LANG.
    Even if I set LANG to C or en_US.ISO8859-1 or whatever, I find that
    LC_CTYPE doeesn't get set.
    
    This started out of idle curiosity, but now I'm beginning to lose sleep
    |-(
    Has anyone solved this before, or can someone point out my mistakes?
    Thanks in advance
    
    	leon
T.RTitleUserPersonal
Name
DateLines
9736.1EVTAI1::SAMIE_Ffrancoise [email protected]Wed May 07 1997 06:012
expr can do it. Try 
if    [ `expr $1 + 1` ] then ...
9736.2Some alternativesUNIFIX::HARRISJuggling has its ups and downsWed May 07 1997 10:3350
    .1 is good, but it outputs an error message when not numeric.  That
    could be fixed by redirecting stderr into /dev/null
    
    	if expr $1 + 1 >/dev/null 2>&1
    	then
    	    	echo numeric
    	fi
    
    Or try:
    
    	if [ -n "`expr $1 : '^\([0-9][0-9]*\)$'`" ]
    	then
    		echo numeric
        fi
    
    Or if you know the max number of digits you could try
    
    	case $1 in
    	    [0-9]|[0-9][0-9]|[0-9][0-9][0-9]|[0-9][0-9][0-9][0-9])
    		echo number is 1 to 4 digits in length
    		;;
    	    *)
    		echo not numeric
    		;;
    	esac
    
    You can extend the [0-9]... expression for as large as you need.  This
    stays within the shell and does not create a new process.
    
    Also you could put your testing in to a borne shell function and make
    then not have to repeat the messy code all over the place, just call
    the function
    
    	is_numeric() {
    	    if [ -n "`expr $1 : '^\([0-9][0-9]*\)$'`" ]
    	    then
    		return 0	# borne shell 0 is true
    	    else
    		return 1	# borne shell 1 is false
    	    fi
    	}
    
    	if is_numeric $1
    	then
    		echo is numeric
    	fi
    
    I'm sure there are other clever ways to do this.
    
    					Bob Harris
9736.3why didn't i think of '^\([0-9][0-9]*\)$' ;-)GIDDAY::STRAUSStalking through my binocularsWed May 07 1997 19:129
    Thanks for both replies.
    
    if [ -n "`expr $1 : '^\([0-9][0-9]*\)$'`" ]
    
    looks like a winner, if only for the obscurity of the syntax ;-)
    
    Thanks again
    
    	leon
9736.4confused about your locale problemsSMURF::WENDYThu May 08 1997 15:267
    What makes you think LC_CTYPE is not being set ? Did you check using
    the locale command ? The 8859-* based locales are in an optional
    subset. IF you set LANG to en_US.ISO8859-1 and it is not installed on
    the system LANG and all the LC_* env varibales default to be C. 
    
    wendy
    
9736.5whoops!GIDDAY::STRAUSStalking through my binocularsThu May 08 1997 18:3613
    Hi Wendy
    
    Sorry, my base note was written in haste (and not a little confusion).
    locale _did_ set LC_CTYPE="C" and LC_CTYPE="en_US.ISO8859-1" for LANG=C
    and LANG=en_US.ISO8859-1 respectively - I didn't check properly :-(
    
    My test using [[:digit:]] probably failed for some other
    brain-fade-related reason ...  Next time, I'll double-check before
    posting.
    
    Thanks
    
    	leon
9736.6BIGUN::nessus.cao.dec.com::MayneA wretched hive of scum and villainyThu May 08 1997 19:185
You forgot to check for a leading "-".

Is "3.14" numeric, or are you just interested in integers?

PJDM
9736.7Just positive integersGIDDAY::STRAUSStalking through my binocularsSun May 11 1997 23:271
    Just positive integers