Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

case statement in ksh script 3

Status
Not open for further replies.

cfoly

Programmer
Oct 9, 2002
3
SE
Hi,

Can I do the following in a case statement of a ksh script;

Check to see if my variable SIZE is >100, >200, >300 etc. If so what is the syntax?

case $SIZE in
>100)
What is the correct syntax for >100, if this is possible?
>200)
...
esac

I can do this with a series of if statements, but was hoping that there was something cleaner.

Any help appreciated.
 
Something like this ?
case $SIZE in
1??) : >=100 && <200
2??) : >=200 && <300
...
*) : all not previously covered
esac

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ181-2886
 
While on this subject, can I, in a case stmt., use text patterns like ...?

case $SIZE in
[1][0-9]{2}) : >=100 && <200
...
 
Iteresting .... I can't get the "+" or the "?" meta char to work in ksh ...

case $SIZE in
5*) echo "works";;
4+) echo "doesn't work";; #match 1 or more preceeding RE
2?) echo "doesn't work";; #match 0 or 1 preceeding RegExp

...

the * works, but the + & ? don't work ...why?

 
I'd go with an if then elif ... fi

if [ ${SIZE} -lt 100 ]
then
:
elif [ ${SIZE} -lt 200 ]
then
:
elif [ ${SIZE} -lt 300 ]
then
:
else
:
fi

or

if ((SIZE<100))
then
:
elif ((SIZE<200))
then
:
elif ((SIZE<300))
then
:
else
:
fi



HTH,

p5wizard
 
Hi

cptk said:
Iteresting .... I can't get the "+" or the "?" meta char to work in ksh ...
I know only [tt]bash[/tt] but appearantly this wildcard behaviour is similar. So probably the [tt]?[/tt] works too, but like in pathname expansion, meaning "? Matches any single character."

Feherke.
 
Hi,

Here is what Korn shell Documentaion says about case statement :

case word in [ [ ( ]pattern [ | pattern ] . . . ) list ;; ] . . . esac
A case command executes the list associated with the first pattern that matches word. The form of the patterns is the same as that used for file-name generation (see FileNameGeneration )


File Name Generation.
Following splitting, each field is scanned for the characters *, ?, (, and [ unless the -f option has been set. If one of these characters appears, then the word is regarded as a pattern. Each file name component that contains any pattern character is replaced with a lexicographically sorted set of names that matches the pattern from that directory. If no file name is found that matches the pattern, then that component of the filename is left unchanged. If FIGNORE is set, then each file name component that matches the pattern defined by the value of FIGNORE is ignored when generating the matching filenames. The names . and .. are also ignored. If FIGNORE is not set, the character . at the start of each file name component will be ignored unless the first character of the pattern corresponding to this component is the character . itself. Note, that for other uses of pattern matching the / and . are not treated specially.


*
Matches any string, including the null string.
?
Matches any single character.
[ . . . ]
Matches any one of the enclosed characters. A pair of characters separated by - matches any character lexically between the pair, inclusive. If the first character following the opening [ is a ! then any character not enclosed is matched. A - can be included in the character set by putting it as the first or last character.
Within [ and ] , character classes can be specified with the syntax [:class:] where class is one of the following classes defined in the ANSI-C standard:

alnum alpha blank cntrl digit graph lower print punct space upper xdigit
Within [ and ] , an equivalence class can be specified with the syntax [=c=] which matches all characters with the same primary collation weight (as defined by the current locale) as the character c.
Within [ and ] , [.symbol.] matches the collating symbol symbol.

A pattern-list is a list of one or more patterns separated from each other with a & or |. A & signifies that all patterns must be matched whereas | requires that only one pattern be matched. Composite patterns can be formed with one or more of the following sub-patterns:


?(pattern-list )
Optionally matches any one of the given patterns.
*(pattern-list )
Matches zero or more occurrences of the given patterns.
+(pattern-list )
Matches one or more occurrences of the given patterns.
@(pattern-list )
Matches exactly one of the given patterns.

!(pattern-list )
Matches anything except one of the given patterns.
Each sub-pattern in a composite pattern is numbered, starting at 1, by the location of the ( within the pattern. The sequence \n , where n is a single digit and \n comes after the n-th. sub-pattern, matches the same string as the sub-pattern itself.

For more infos :
 
Code:
$ cat casenum  
#!/bin/ksh
for i in 123 234 a12 12a +150 -50 299 200 250 +201
do
 case $i in
  ?([+])1@([0-9])@([0-9])) echo $i is in the range 100 to 199;;
  ?([+])2@([0-9])@([0-9])) echo $i is in the range 200 to 299;;
  -*([0-9])) echo $i is a negative integer number;;
  *) echo $i is not a number;;
 esac
done
$ ./casenum  
123 is in the range 100 to 199
234 is in the range 200 to 299
a12 is not a number
12a is not a number
+150 is in the range 100 to 199
-50 is a negative integer number
299 is in the range 200 to 299
200 is in the range 200 to 299
250 is in the range 200 to 299
+201 is in the range 200 to 299

I still prefer if-then-elif-fi decision tree in this instance. I code a "(( i=i+0 )) 2>/dev/null" first to make sure i is an integer and proceed to if-then... if retcode is 0.
(( i=i+0 )) also gets rid of the fractional part should i contain a real number...


Interesting point on AIX ([0-9]) works, but ([:digit:]) doesn't?



HTH,

p5wizard
 
Thanks for all the help.

Think that I am going to go with the ifelse option after all. Its more readable and is evaluating the variable as an integer rather than looking at its character sequence.

p5wizard, in your expression ?([+])1@([0-9])@([0-9]) what is the @ symbol doing?
 
@(pattern-list )
Matches exactly one of the given patterns.

if you can't be bothered to read through it.

Code:
?([+])1@([0-9])@([0-9])
?([+]) either a plus-sign or not
      1 literal 
       @([0-9]) one digit exactly
               @([0-9]) again, one digit exactly

so
+100 to +199 or 100 to 199 match
200 , 1990 or 10 don't match


HTH,

p5wizard
 
Yes, Annihilanic

@([[:digit:]]) works as well.

Within [ and ] , character classes can be specified with the syntax [:class:] where class is one of the following classes defined in the ANSI-C standard:

alnum alpha blank cntrl digit graph lower print punct space upper xdigit

so [0-9] becomes [[:digit:]]

and @([0-9]) is equivalent to @([[:digit:]])



HTH,

p5wizard
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top