Argument passing

How to pass the alphabet character as a argument in case and in if block?

ex:

c=$1
if [[ c -eq a-z ]]
then
echo "alphabet"
 
case $1 in
a-z) echo "the value is a alphabet"
c=$1
if [[ $c =~ "[a-z]" ]]
then
    echo "alphabet"
fi
c=$1
case $c in
    [a-z] ) echo "alphabet" ;;
    [0-9] ) echo "number" ;;
    *     ) exit
esac

I tried this, but im getting error while using this : =~ unexpected

#!/bin/ksh
set -x
c=$1
if [[ $c -le 9 ]]
then
     echo "Digit"
elif [[ $c =~ "[a-z]" ]]
then
     echo "letter"
else
     echo "More than one char in length"
fi
 
case $c in
     [0-9] ) echo "The value is a number"
          ;;
     [a-z] ) echo "the value is a alphabet"
          ;;
     *) echo "Other"
          ;;
esac
 
 
./file 4 
Syntax error at line 8 : `=~' unexpected 

Try using:

if [ `echo $c | grep -e "[a-z]"` ] ; then
  echo "found"
else
  echo "no found"
fi

cheers,
Devaraj Takhellambam

#!/bin/ksh
set -x

c=$1
if [[ $c = @([0-9]) ]]
then
echo "Digit"
elif [[ $c = @([a-z]) ]]
then
echo "letter"
else
echo "More than one char in length"
fi

case $c in

@([0-9]) ) echo "The value is a number"
;;
@([a-z]) ) echo "the value is a alphabet"
;;
*) echo "Other"
;;
esac

Thanks Devtakh and Anbu... those are working well!!

Given your original problem statement and using only features defined by the POSIX standards and the Single UNIX Specification, you could try:

if [ $# -ne 1 ]
then    echo "Usage: $(basename $0) single_character" >&2
        exit 1
elif [ ${#1} -eq 0 ]
then    echo "$(basename $0): argument is an empty string" >&2
        exit 2
elif [ ${#1} -gt 1 ]
then    echo "$(basename $0): argument is more than a single character" >&2
        exit 3
fi
case "$1" in
([[:digit:]])   echo "digit";;
([[:alpha:]])   echo "letter";;
(*)             echo "other";;
esac

DonCraguns suggestion is a very good one, but you showed - apart from syntactical errors - some lack of consideration. Lets go over your script:

#!/bin/ksh
set -x
c=$1
if [[ $c -le 9 ]]

This is the first problem: you expect a user to enter what you think he will enter. Never trust user input - in no way at all. The expression "$c -le 9" is an integer comparison and this in turn depends on only an integer being supplied by the user. How would your script react to this input:

/your/script blabla

or this:

/your/script "all hell breaks loose on this one" 

In the first case your comparison will fail because you try to compare integer to string and in the second case it will even fail at c=$1 because the multi-word into which "$1" expands into will break the line. "$c" wil be assigned "all" (the first word) and the other words will lead to syntax errors.

To avoid the multi-word problem use quoting:

c="$1"

To avoi the integer-string problem first make sure your input is indeed an integer before you use integer comarison. This is called type-checking. Bottom line: always be paranoid about user input and assume it will make the least sense possible. It usually does.

elif [[ $c =~ "[a-z]" ]]

Even if this would work as expected it would again break on multi-word input because of the missing quoting. Further, what would happen with this input:

c="A"
...
elif [[ "$c" =~ "[a-z]" ]]

In fact it would NOT match at all! The reason is that UNIX IS CASE-SENSITIVE! "[a-z]" and "[A-Z]" are different and if you want to make sure it is indeed a character (as opposed to a lowercase character you have to test it for both:

c="A"
...
elif [[ "$c" =~ "[a-zA-Z]" ]]

Another thing is a further false assumption: you test (i assume now your tests would do what they are meant to do) for numbers smaller than 10 and single characters and if both tests fail you deduce that it has to be a multi-character string. What about numbers bigger than 10? What about strings like "!", which would fail on both tests before too?

I hope this helps.

bakunin

Don Cragun:

elif [ ${#1} -eq 0 ]
then echo "$(basename $0): argument is an empty string" >&2
exit 2

./file 0
This "0" is taken as a single(1) argument, so the elif statement is skipping
Finally the result shown is:
output :
digit

I don't understand your comment.

If the script I provided is invoked with the single argument 0 then $# (the number of positional parameters) is 1 and ${#1} (the number of characters in the 1st positional parameter) is 1. So the [ ... ] commands in the if and both elif statements evaluate to false so no diagnostic is printed. Therefore the code continues with the case statement to determine what type character was supplied as the value of the single character given as the one and only operand to the script. Since 0 is in the digit character class, the script reports that 0 is a digit.

A way to get the diagnostic "file: argument is an empty string" to print would be to execute the command:

./file ""

since the number of characters in the empty string ( ${#1} when $1 is the expansion of "" in the shell after quote removal processing) is 0.