Condition checking

Dear all

That's another problem from me, i wanna do a lot of if statement checking for correct input by user, will be prompt input again if the input not meet the requirement defined by If or while statement...

like this one ....

while [ $a != "a1232132" -o $a != "asdfsdaf" ....... \
$a != "basdfd" -o $a != "bj-sdf"..... ]

I know it's less effiency write the program like this if too many compare string occured, can anyone help me find a best way to solve this sort of verification....

thanks in advance!!!

Here is one way...

#! /usr/bin/sh


done=0

while [ $done -eq 0 ] ; do
        done=1
        echo enter value --
        read val
        case $val in
        111)  echo do 111 thing
              ;;
        222)  echo do 222 thin
              ;;
        333)  echo do 333 thing
              echo do more 333 stuff
              ;;
        *)    done=0
              echo fumble
              ;;
        esac
done

My 2 cents here: I notice that the logical condition "a not equal dhgsf or a not equal hdhdhss or a not equal zxhcgvxhsg (etc)" is ALWAYS TRUE :slight_smile:

You probably meant -a (and) instead of -o (or) :wink:

Us frog prince, Yes, that's right, should be use AND (-a) here.

HI Perderabo, you probably misunderstand what I means, ok here is a example:

echo �Please enter item name or ID: � 		
read name
while [ $name != �name1� -a $name != �name2� -a\\ $name != �stock1�	$name != �desk� -a ....... ]		
                                          \# check whether have in store
do 
	echo �We have no such item!!!�
done
echo � �

echo �Item name: � $name
...

the question here is: if there are many many kind of items, obviously you must waster time to write long coding to include all of items you have, therefore any other methods suitable for this sort of problem?

If the list is that huge you might need to go through a text file, as an input. Won't speed up the execution, though.

I can't think about something other than what Perperado already suggested:

ok=0
while [[ $ok -eq 0 ]]
do
echo "Choice? \c" ; read choice
case $choice in
stock1) ok=1;;
desk) ok=1;;
*) ok=0;;
esac
done
echo "Your choice was: $choice"

Your example doesn't make sense. A "while" does not have two sections like that. You can't do stuff between the test and the "do"! It looks like you might mean to use an "if" statement? Also a "while" implies looping until something changes. It look like a legal value will give you an infinite loop. And if the user enters an illegal value, are you just going to give up? Or loop until you get a legal value?

And in any event, if there are, say, 10 strings that you must check for, then you need to check for them all. No way around that. But rather than code a lengthy "if" statement ( or "while" statement), I would go with a "case" statement.

if you'd find it easier to maintain a file of products & check against that, you could do a grep & check the value of $? to see if it is in the file.

eg.

grep -x $name productfile 1>/dev/null 2>&1
if [ $? -eq 0 ]
then echo "item name :" $name
else echo "not found :" $name
fi

the -x option limits the grep to exact matches, that is if productfile contains

a123123
a321321
etc.

the grep will only match "a123123" & would not match a name such as "a123"

Hope this helps.

Kevin Pryke
yes, it's worked, but -x option not within the standard grep, it must set path to /usr/xpg4/bin on my system...solaris
and the data file must be write item name line by line...

How about SED, can u make it?

They may be a very simple way of doing it in sed but I don't use sed really, anyone else?

Also I don't use solaris (I'm on sco using a bourne shell) but I imagine there is an equivalent option to the -x.

if you type

man grep

it will give you a list of options, look for one that says something like

-x Displays only exact matches of an entire line.

I'm not quite sure what you mean by "the data file must be write line by line". If it's the output of the echo that you want to write to a file, do this

echo $name >> outputfile.dat

which will append the $name to a file outputfile.dat. However you must remember to initialise the file each time you run the script so at the start put

> outputfile.dat

which will empty it.

Post back with any further problems.

I agree with Perderabo.

A case statement will be the best. Because you will only have to write a short code statement for each one and any thing that doesn't match will kick out to the main menu.

Case is superior especially when you need to do a great deal of validation or have many different tasks to choose from.

I would also use a flag to turn on when any one of the parameters are met so that any subsequent answers for that part of the case will be ignored and kick to the menu again. If it matches your user shouldn't need to answer it again.

Case is very easy to format, don't hesitate to use it.

case $VAR in

VAR1 ) Do some statement ;;

VAR2 ) Do different statement ;;

VAR3 ) Do another different statement;;

  • ) Do default statement or return to menu and exit from CASE ;;

esac

:cool:

HI Kelam_Magnus
i don't think so, the wildcard can be represent all combination which not match the string, but how about the rest, if you must excatly match word by word in string? assume, match any 1000 numbers in 1-100000, how to write the code, 1 by 1?

To: Kevin Pryke

 I mean that the file would be like this format:

...
word1
word2
word3
word4
...

Yes, it will not function or prompt error if you append a word beside the word1, you be told" word 1 not found"

...
word1  word100
word2
word3
word4
...

The wildcard in the case statement will only catch $VAR when it does not match as the ;; at the end makes it skip the rest of the checks when it hits a match.

It seems to me you'll either have to type all your codes into a case statement or into a file - it's up to you really.

My way of doing it using a grep was just a suggestion of another way, I thought you might already have a file in the format of

word 1
word 2
word 3
word 4
etc.

if you have a file

word 1 word 2
word 3
word 4

I know it won't work, you may be able to manipulate if somehow with sed/awk but I'm not sure.

I'm off work till Monday now, the World Cup is calling me.

trynew,

Using Case may mean you will have to write long code. If you code checking is as extensive as you suggest, I can't think of another way to do it. A for loop or a while loop will have to contain many if statements. Case seems to me to be the best way to go.

Here is my further explanation...

For case to work any input must be 1 variable string at a time. if you have 1000 variables, you will need 1000 groups of lines in your case statement.

If you are executing a loop to read in data, any data on one line of your input must match a particular case element. Otherwise it will fall out of the case with the *) statement.

If your input file has more than one column, I suggest this. Of course if you have a delimeter, put a -F? after the awk.

cat filename | awk '{ print $1 } >> newfile.out
cat filename | awk '{ print $2 } >> newfile.out
cat filename | awk '{ print $3 } >> newfile.out
cat filename | awk '{ print $4 } >> newfile.out

And so on, until you have cleared all the columns down to only one column. You will need this in for the case to work properly, if I read your data correctly.

You need to change:

word1 word2 word3
word4 word5 word6

Into:

word1
word4
word2
word5
word3
word6.....

This will allow the looping statement to feed into the case statement.

Hope this helps... Please get back with any other info.

:smiley:

Thanks, Kelam_Magnus and Kevin Pryke

Got to be relax for today, watch world cup... England vs Brazil

I bet  england will win!!! Beckham..owen..oh yes!!!goal................

anyway, england lost....sigh

thanks you all