I'm writing a program that takes input from the user of a phone number or a name then either tells them if that entry doesn't exist in a text document or returns the entry if it does exist. But if they enter a name AND number it either returns the entry if it exists or adds it to the document.
To do this involves lots of if statements etcetc but to start I need to know how to tell the program if the user has only put in a number or name or if they've put in both name and number.
Long rant short is there a statement that tests if 1 or two arguments have been inputted?
would the following work?
if [ $1$2 ]
#test for number and name in document
elif [ $1 ]
#test if its a valid number or name then test if it's in document
Thanks for your help.
Well the first variable is 1 argument or 2, then (if 1) number or name then validating the number or name then checking if the number/name is in the document (if 2) validating the number and name, checking if it's in the document and adding.
I was thinking having an outer if statment then cases in them to validate with if statements in those to check the document. Ah nesting, gotta love it.
With your [ -n $2 ] I'll be able to start it correctly.
Thanks very much
#!/bin/sh
NAME= NUMBER=
while $# -gt 0; do
if echo $1 | grep -qv '[^0-9-]'; then
# $1 contains only digits and dashes
test -n "$NUMBER" && { echo "Too many numbers"; exit 1; }
NUMBER=$1
else
test -n "$NAME" && { echo "Too many names"; exit 1; }
NAME="$1"
fi
shift
done
# Now process $NAME and $NUMBER if they aren't blank
I think grep -qv '[^0-9-]' is clever.
It quietly returns true if the value piped in does not contain any characters that are not digits or hyphens.
That is, if true, it only contains those characters.
-------------
Oops. I for forgot the brackets. The 'while' line should be:
while [ $# -gt 0 ]; do
or
while test $# -gt 0; do
lol well my next question was how do I determine input is digits or not?
I tried the if echo $1 | grep -qv '[^0-9-]'
but it doesn't appear to accept it as false if I enter a name ie enter 12345678 and it does the number part enter bob and it says invalid number.
Also after I get that figured out how do I get the line from the document that contains the name or number ie entered "bob jones" and it was found in the document. It needs to echo that result
ie Bob Jones 12345567
is there a grep option that returns the line itself?
Have you thought of maybe adding an option to your script:
script.sh --number 123456789
script.sh --name "Jim Jones"
That way you would be able to determine what type of validation you should apply. Also you may want to try this regular expression to match the number:
[0-9-]+
It will match more than one instance, I think yours was stopping at the first instance the expression was satisfied.
Yay! thanks for that. I got the check numbers grep thing working fine but it still seems to have a problem with how many arguments were entered. If i use [ -n $2 ] it just runs like there is one no matter what,
[ $# -gt 0 ] always thinks there is 2.
---------- Post updated at 10:51 PM ---------- Previous update was at 10:41 PM ----------
Here's my code just in case it's something obvious i've done that's stopping it from working:
if [ -f $directory ]
then
#This will take the number and/or name from the user storing it into $input
echo -e "Input name or/and number: \c";
read input
#This if statement checks to see if the user inputted 1 argument ie name OR number or 2 ie name AND number
if [ $# -ne 2 ]
then
#This line checks to see if the input contains only digits or hyphens
if echo $input | grep -qv '[^0-9-]'
then
#This case will take the input and check it is a valid number (8digits not starting with 0)
case $input in
[1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9])
continue;;
*) echo "invalid number"; exit
esac
else
#This case will test if an inputed name is valid.
case $input in
[!\ a-zA-Z]*) echo "invalid name" ; exit
continue ;;
*[a-zA-Z]*)
continue ;;
esac
fi
#If the name or number was valid this block of commands will run, checking the #directory for the name/number and returning either no such entry or the entry itself.
grep "$input" teledir.txt>/dev/null
work=$?
if [ $work -ne 1 ]
then
grep "$input" teledir.txt
else
echo "No such entry"
fi
#If 2 statements were inputted this block of commands is run (ie similar but if #entry doesn't exist it adds it instead of returning no such entry
else
echo "2 arguments entered"
fi
#Tells the user the Teledir.txt was not found
else
echo "Teledir.txt does not exist in this directory"
fi
Is it perhaps because its an inputted value inside the program so it doesn't count as a command line? That might be why it's not counting arguments. Is there a way to remove the need for the user input line so they'd type $sh phone.sh "bob" 1234567 instead of doing it in the program itself?
I think it is wasteful. There is no need to use an external command to determine whether a string contains another string or character. Use case. For example:
case $1 in
[!0-9-]* | *[!0-9]* ) echo contains non-numbers ;;
*) echo numbers only ;;
esac
Are you saying that the syntax of [!...] as described in the Filename Expansion section of the Bash manual is not POSIX and not portable?
Or do you just mean that Bash in general is not POSIX and not portable?
Oh! I just found a document from the OpenGroup that describes Pattern Matching Notation which says, A bracket expression starting with an unquoted <circumflex> character produces unspecified results. Great! A built-in gotcha.
It is true that Bash has extensions beyond POSIX, and therefore if something works perfectly in the Bash shell, there is no guarantee it will work in some other shell. For that reason there is wisdom in insisting on POSIX compatibility as you do.
But one has to consider the context in which one codes. Many scripts will never be used outside of Bash, or even be seen by someone who holds Bash extensions in other than the highest regard. If one writes a Perl or Python script, it's not wrong to require that it only be run on systems with Perl or Python installed. I don't think it's out of order to view Bash scripts similarly.
If you use non-standard syntax, you should expect to have problems.
Absolutely.
There is a major difference between a shell and perl or python. A shell is a necessary component of a system; perl and python are not.
When I write a script, I try to write it using a portable (i.e. POSIX) syntax. If writing for bash, I may use bash extensions, but I never use bash-only syntax for something that can be coded with POSIX syntax.
Okay it turned out that no matter what I do $# wasn't returning anything but 0 which is why it wasn't working correctly. I'm looking into the problem now.
Ha figured it out. Apparently I was right about it not liking to count arguments in a variable, it had to be added inthe command line when the script itself was called.
Thanks for your help all. My program works great now THANKYOU!