home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.unix.shell
- Path: sparky!uunet!mcsun!sunic!ugle.unit.no!news
- From: Harald.Eikrem@delab.sintef.no
- Subject: Re: Distinguish between numeric & nonnumeric char strings in shell ?
- In-Reply-To: ramakris@CSGRAD.CS.VT.EDU's message of 4 Sep 92 07:02:38 GMT
- Message-ID: <1992Sep4.191337*Harald.Eikrem@delab.sintef.no>
- Sender: news@ugle.unit.no (NetNews Administrator)
- Organization: SINTEF DELAB, Trondheim, Norway.
- References: <9209040702.AA06629@csgrad.cs.vt.edu>
- Date: 4 Sep 92 19:13:37
- Lines: 91
-
- ! How does one distinguish between a number and a nonnumeric
- ! character using shelltools (sh/csh, awk, sed, expr, etc) ?
-
- In a /bin/sh script, to test if a parameter (or a variable) truly is
- an integer number, you'd have to find out if that shell (/bin/sh)
- groks character class inversion, like:
-
- [!0-9] matches any char except digits
-
- and if it does, you can do something like:
-
- while :; do
- case $arg in
- *[!0-9]*)
- echo >&2 "Argument is non-numeric"
- echo -n >&2 "Reenter: "
- read arg
- ;;
- *) break
- esac
- done
-
- If the shell does not understand character class inversion, you may
- still be able to perform a test like this without applying external
- progs (sed/awk/expr/...), but certainly it will be more cumbersome,
- like e.g.:
-
- case $arg in
- *[^A-/:-~]*)
- echo >&2 "Argument is non-numeric"
- ......
-
- where ^A denotes a real control-A character in the script.
- Or if you can't get that to work, here comes a last resort:
-
- case $arg in
- [0-9] | [0-9][0-9] | [0-9][0-9][0-9] | [0-9][0-9][0-9][0-9] |\
- [0-9][0-9][0-9][0-9][0-9] | [0-9][0-9][0-9][0-9][0-9][0-9] |\
- ......
- ......
-
- You get the picture.
-
-
- ! I am trying to validate the IP address typed in by the user.
- ! I isolate the four components and check each one to see if lies
- ! within the legal range (0..255). In the event the user types, say,
- ! tom.jack.joe.jim, I want to be able to flag an error. However the
- ! IF statement, marked (+) in the fragment below, fails even if a 4
- ! component string such as "tom.jack.joe.jim" is entered.
- ! Any suggestions ?
-
- Supposing you actually want the script to decide whether it's a simple
- hostname, a domainified hostname or an IP (decimal) numeric address,
- I'd say that a test like
-
- case $address in
- *.*.*.*.*) # domainified hostname
- ;;
- [1-9]*.[0-9]*.[0-9]*.[0-9]*) # IP numeric address
- ;;
- *.*) # domainified hostname
- ;;
- *) # simple hostname
- esac
-
- would suffice, because the likelihood of ever finding a true domain-
- name that would match the 2.nd case is none.
-
- But of course, if you dont trust the users to know how to enter a
- dotted 4-digit IP address, it'll take more effort to get it checked.
- To check each of the IP address elements, do something like:
-
- saved_args=$@ # only if $@ is to be used later on
-
- _IFS=".$IFS"
- set -- $address
- IFS="$_IFS"
- if [ $1 -lt 1 -o $1 -gt 223 -o $2 -gt 254 -o \
- $3 -gt 254 -o $4 -lt 1 -o $4 -gt 254 ]; then
- echo >&2 "Argument is not a legal IP numeric address"
- ......
- ......
- fi
-
- set -- $saved_args # if need be
-
-
- I'm not going to speak about sed/awk/<whatever> solutions.
-
- ~~harald E.
-