Unix Shell basic loop massive n00b

hey guys
I would really appreciate some help, i need to do a project for a job that requires minimal UNIX scripting and im REALLY stuck

basically Im stuck at what i believe is something really simple but i just dont have a clue how to do it efficiently and properly and i REALLY appreciate some help

Basically i have a loop at which someone has to enter a string of 3 numbers.

-I want the code to check that the string is numbers only
-check that the numbers have not been already signed to someone else in the users.db file
-restrict the number of numbers to only 3.

  • each time the user inputs the number wrong i want it to be allowed to correct and tell why he has to re enter it.

This is the best i could came up with but IM REALLY suck and im at a short UNIX course (1 week) for a job....

Can anyone please tell how do i make the loop properly??

this is the best i could came up with... and i KNOW is crap... but i just dont know best........ I would really appreciate some guidance plz

#!/bin/bash
echo -e  "Create a new record\n"

fSID (){
read -p "Please enter staff ID: " cSID
}

fSID

gcSID=$(grep $cSID users.db | cut -d ":" -f1 | tr [":"] [" "])
wcSID=$(echo $cSID | wc -c) 

case "$cSID" in
      [!0-9]*         ) echo -e "The staff ID should contain only digits\n "
	  sleep 0.5
	  fSID;;
                  
esac  
    while [ $wcSID -gt 4 ]; do 

  read -p "Please enter a value: " cSID 
wcSID=$(echo $cSID | wc -c) 
echo $wcSID
done 
read -p "u passed to stage 2! gratz" st2

Check that the length is three. [ "${#STR}" -eq 3 ]

Check that it's all digits. [ -z "${STR/[0-9]*/}" ]

Check that it's not in the file. ! grep $ID user.db #??? not perfect but best I can do without knowing what user.db looks like

So

STR=""
until [ "${#STR}" -eq 3 ] && [ -z "${STR/[0-9]*/}" ] && ! grep "$STR" user.db > /dev/null
do
         read STR
done

Thank you!!

I really appreciate that you took the time to help me out :b:

However, how do I tell the user then why they are re inserting the information then?
specially if the entry is already in the user.db
coz that code will do it over and over again until is right but the person will not know why they have to re enter the info

Thank you again!
u r a life saver!

I asked what the users.db looked like too, and noted that my grep solution probably doesn't do what you want because I don't know what users.db looks like...

while true
do
        read ID
        if [ "${#ID}" -ne 3]
        then
                echo "wrong number of digits"
                continue
        fi

        if ! [ -z "${ID/[0-9]*/}" ]
        then
                echo "Not all digits"
                continue
        fi

        if grep "$ID" users.db > /dev/null
        then
                echo "The string '$ID' exists anywhere at all in users.db"
                continue
        fi
        break # get out of loop
done

the db looks like thi

the ID is the first one

Thank you!!

grep "^${ID}:" users.db > /dev/null then. ^ means beginning of the line.

thank you!!

Another question:

how would i be a really cool way (the way u do it) to retrive the one b4 the last ":".
Shall i use "cut" and "tr" or there is an easier way?

also how could i save it to an array? ( you will prob know how to do it in 1 step and i would do it in 300)

Thank you so much!!... you prob saved me 4 hrs trying to figure it out and it would never look as neat!

---------- Post updated at 03:38 PM ---------- Previous update was at 03:27 PM ----------

Btw i ran the program and it returns an error after i written down the string

and it doesnt show any message
why is that?

---------- Post updated at 03:50 PM ---------- Previous update was at 03:41 PM ----------

3] should be 3 ]

Love ya!

Another question:

how would i be a really cool way (the way u do it) to retrive the one b4 the last ":".
Shall i use "cut" and "tr" or is therean easier way?

also how could i save it to an array once is all checked up? ( you will prob know how to do it in 1 step and i would do it in 300)

Thank you so much!!... you def saved me 4 hrs trying to figure it out and it would never look as neat!:D:D:b::b:

# modifies global variables ID, NAME, SURNAME, D1, D2, D3
function findid
{
        # Read entire file line-by-line hunting for $1
        while IFS=":" read ID NAME SURNAME D1 D2 D3
        do
                # Return success if we find it
                [ "$ID" = "$1" ] && return 0
        done <users.db
        # didn't find it.  return error.
        return 1
}

if findid 999
then
        echo "Found ID $ID name $NAME surname $SURNAME d1 $D1 d2 $D2 d3 $D3"
else
        echo "Couldn't find $ID"
fi

thank you!
you are a star! =)
i reckon that to write into the db
i change the read for write?

nope. To write to it, you do something like

echo "a:b:c:d:e:f" >> users.db

Note the double->. A single > will OVERWRITE the file instead of appending it so be careful.

Thank you sooooooo much!!

Put a space after the 3 here: if [ "${#cSID}" -ne 3]

To assign last element of line to end of array:

my_array[${#my_array[@]}]=$(sed -n "s/^$cSID.*://p" users.db)

Thank you!

although i got a bit confused with the array thing given that i got an array of 6 inputs
if this

my_array[${#my_array[@]}]=$(sed -n 's/^$cSID.*://p users.db
')

[/quote]

is the last element
how do i select the other 5 ?

thx

Oh sorry, I missunderstood your request - to load the line for cSID into an array you could use:

IFS=: my_array=( $(grep "^$cSID" users.db) )

Example:

$ cat users.db
423:name:surname:18:14:5
666:Ferris:Lucy:15:6:17
069:Chong:Annabel:15:20:16
987:Marple:Mike:13:19:12  
 
$ cSID=069
 
$ IFS=: my_array=( $(grep "^$cSID" users.db) )
 
$ echo Items=${#my_array[@]}  3rd=${my_array[2]}
Items=6 3rd=Annabel