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