I had already solutions in ksh for that but wanted to see them with expr (which would be a true Bourne shell solution) and also I did them in Perl.
A number is meant to be a sequence of digits ie. 1234.
An integer is either a number or a number prefixed with a minus sign ie. 1234 or -1234.
#!/bin/sh # Test if arg $1 is a number ######################################## isNum1() { ksh -c "[[ \"$1\" = +([0-9]) ]]" return $? } isNum2() { [ `expr "$1" : '[0-9][0-9]*$'` = "0" ] && return 1 return 0 } isNum3() { perl -e 'exit 1 unless($ARGV[0]=~/^\d+$/)' -- "$1" } # Test if arg $1 is an integer ######################################## isInt1() { ksh -c "[[ \"$1\" = *(-)+([0-9]) ]]" } isInt2() { [ `expr "$1" : '[0-9][0-9]*$'` = "0" -a `expr "$1" : '-[0-9][0-9]*$'` = "0" ] && return 1 return 0 } isInt3() { perl -e 'exit 1 unless($ARGV[0]=~/^-?\d+$/)' -- "$1" # Here's an alternative, better to read in Perl maybe but two commands and a pipe: # echo "$1" | perl -n -e 'exit 1 unless(/^-?\d+$/)' } # Test suite for i in 204 -13 +88 1-2 4+5 46.09 -7.2 a abc 2x -2x t56 -t5 "2 4" do isNum1 "$i" && echo Num1 $i isNum2 "$i" && echo Num2 $i isNum3 "$i" && echo Num3 $i isInt1 "$i" && echo Int1 $i isInt2 "$i" && echo Int2 $i isInt3 "$i" && echo Int3 $i done Executing the script results in Num1 204 Num2 204 Num3 204 Int1 204 Int2 204 Int3 204 Int1 -13 Int2 -13 Int3 -13 i.e. only the first entry is a number and the first two entries are correctly identified as integers.One drawback to expr is that it supports only basic regular expressions i.e. some useful special characters like + or '?' cannot be used and thus ksh and Perl provide more concise solutions to the above problem.
No comments:
Post a Comment