Insert Contacts to a .csv file using terminal and shell script - shell

Hi I want to make a script that inserts contacts to a .csv file. It asks the user to type First Name, Last Name, and Phone number and then the output will be saved in a file named contacts.csv.
For example : John,Dawson,2102983187
Tried this but want to separate output with commas as it's on the example and it has to be in a loop.
#!/bin/bash
IFS=','
touch contacts.csv
echo "What's your contact's first name?"
read fname
echo "$fname" | grep '^[[:upper:]]\+[a-z]\{0,\}' >> contacts.csv
echo "What's your contact's last name?"
read lname
echo "$lname" | grep '^[[:upper:]]\+[a-z]\{0,\}' >> contacts.csv
echo "Whats your contact's phone number"
read phone
echo "$phone" | grep '[0-9]\{10\}$' >> contacts.csv

#!/bin/ksh
read fname?"What's your contact's first name? "
read lname?"What's your contact's last name? "
read phone?"What's your contact's phone number? "
[[ $fname =~ ^[[:upper:]][a-z]+$ ]] || { echo "$fname should be uppercase first char followed by lowercase chars" ; exit 1; }
[[ $lname =~ ^[[:upper:]][a-z]+$ ]] || { echo "$fname should be uppercase first char followed by lowercase chars" ; exit 2; }
[[ $phone =~ ^[[:digit:]]+$ ]] || { echo "$fname should be digits only" ; exit 3; }
echo "$fname,$lname,$phone" >> contacts.csv
Changing IFS isn't necessary. IFS=Input separator, and from your checks, I assume, that you don't want , in your input.
Read can provide a prompt, no need to use echo.
I would check all inputs first, and then write to output.
If you put the block between
while true; do
...
done
An empty input will stop the processing

Related

Making flashcards with "select" command

So I have a file called "nouns" that looks like this:
English word:matching Spanish word
Englsih word:matching Spanish word
..etc etc
I need to make a program that list all the English words with an option to quit. The program displays the English words and ask the user for the word he wants translated and he can also type "quit" to exit.
This is what I have so far that shows me the list in English
select english in $(cut -d: -f1 nouns)
do
if [ "$english" = 'quit' ]
then
exit 0
fi
done
I know that I need to run a command that pulls up the second column (-f2) by searching for the corresponding English word like this
result=$(grep -w $english nouns|cut -d: -f2)
My end result should just out put the corresponding Spanish word. I am just not sure how to get all the parts to fit together. I know its based in a type of "if" format (I think) but do I start a separate if statement for the grep line?
Thanks
You need a loop in which you ask for input from user. The rest is putting things together with the correct control flow. See my code below:
while :
do
read -p "Enter word (or quit): " input
if [ "$input" = "quit" ]; then
echo "exiting ..."
break
else
echo "searching..."
result=$(grep $input nouns | cut -d ':' -f 2)
if [[ $result ]]; then
echo "$result"
else
echo "not found"
fi
fi
done
dfile=./dict
declare -A dict
while IFS=: read -r en es; do
dict[$en]=$es
done < "$dfile"
PS3="Select word>"
select ans in "${!dict[#]}" "quit program"; do
case "$REPLY" in
[0-9]*) w=$ans;;
*) w=$REPLY;;
esac
case "$w" in
quit*) exit 0;;
*) echo "${dict[$w]}" ;;
esac
done
You want to run this in a constant while loop, only breaking the loop if the user enters "quit." Get the input from the user using read to put it in a variable. As for the searching, this can be done pretty easily with awk (which is designed to work with delimited files like this) or grep.
#!/bin/sh
while true; do
read -p "Enter english word: " word
if [ "$word" = "quit" ]; then
break
fi
# Take your pick, either of these will work:
# awk -F: -v "w=$word" '{if($1==w){print $2; exit}}' nouns
grep -Pom1 "(?<=^$word:).*" nouns
done

New Employee bash script

I am new to bash scripting. I have a script that i am working on for a school project and its not working as expected. I keep receiving a error on my if then statements.
#!/bin/bash
echo –e “Would you like to add a new employee’s information? y/n \n”
read EMPLOYEE
if [ $EMPLOYEE = “y” –o $EMPLOYEE = “Y” ]
then
echo –e “Please enter employee’s first name  \c”
read FIRST
echo –e “Please enter employee’s last name  \c”
read LAST
echo –e “Please enter empolyee’s ID  \c”
read ID
echo –e “$FIRST\t$LAST\t$ID” >> database
fi
echo –e “Would you like to search for an employee? y/n \n”
read SEARCH
if [ $SEARCH = “y” –o $SEARCH = “Y” ]
then
echo –e “Enter the first name, last name or employee ID to search for.  \c”
read WORD
grep “$WORD” database
fi
With even a bash version 3 the following should work as you intended and be somehow shellitical correct ;-)
#!/bin/bash
printf "Would you like to add a new employee’s information? y/n \n"
read -r EMPLOYEE
if [ "$(tr '[:upper:]' '[:lower:]' <<<"$EMPLOYEE")" = "y" ]
then
printf "Please enter employee’s first name : \c"
read -r FIRST
printf "Please enter employee’s last name : \c"
read -r LAST
printf "Please enter empolyee’s ID : \c"
read -r ID
printf "%s\t%s\t%s" "$FIRST" "$LAST" "$ID" >> database
fi
printf "Would you like to search for an employee? y/n \n"
read -r SEARCH
if [ "$(tr '[:upper:]' '[:lower:]' <<<"$SEARCH")" = "y" ]
then
printf "Enter the first name, last name or employee ID to search for. : \c"
read -r WORD
grep "$WORD" database
fi
Notes on refactoring/repair:
Do not rely on echo -e in most cases printf works better and looks more like coding,
use read -rto mot mangle backslashes on input,
quote variables from input (with real ASCII quote characters), as the shell parser otherwise does funny things,
do not test against y and Y but simply lowercase the string received to only compare one variant.
Use some indent concept to track, and
use a shell linter as suggested by a commenter already (that one works nicely currently).
The above code does have no errors indicated in the above mentioned linter.
Small task for as exercise for the reader (thanks andlrc :)
Use lowercase variable names and I amend meaningful names
Enjoy the learning of the shell coding!

why the sed command is not replacing the text

updated code in which i got my sed command runnning, but the actual part of finding the fname and replacing with fname1 is not actually happening
3)
echo " Enter Student id number you would like to modify"
read sID
grep ^$sID stud
if [ $? -ne 0 ]; then
echo " The student id entered, does not exist"
else
echo " Enter the students first name that is being changed and than their new name to be: "
read fName
read fName1
sed -i s/'$fname'/'$fname1'/g stud
echo " Enter the students last name: "
read lName
echo " Enter the gender of the student(M for male or F for female): "
read gndr
echo " Enter the date of birth of the student(formate equals mm/dd/yr): "
read dob
echo " Enter the status of the student(freshman, sophomore, junior, or senior): "
read sts
echo " Enter the gpa of this student: "
read gpa
fi
;;
short answer: remove the single quotes.
putting the variables inside the single quotes makes them not be expanded to their values but to use the literal values in quotes.
so considering a=1:
echo '$a'
echoes: $a
while:
echo $a ${a} "$a"
echoes: 1 1 1
I think the quotes are there because you could be trying to do it in a more usual form instead:
sed -i 's/'$fname'/'$fname1'/g' stud
but you should use:
sed -i "s/$fname/$fname1/g" stud
to keep it simple and because this way the command will not fail if there is a blank space in the variables, however it could fail if there is another non alphanumeric character used by sed.
REFERENCE:
http://tldp.org/LDP/abs/html/quotingvar.html

What is wrong with my DOB Sorting script

I keep getting an error on line 22: [!: command not found
My script Asks for a name, phone number, and date of birth and then amends these details to a comma separated value file called “birthday.csv”.
It then Sorts “birthday.csv” by date of birth. The newly sorted file is then displayed and calculates their age.
Can someone take a look at my script and see why this is popping up.
#!/bin/bash
a=0
while [ $a -lt 2 ];
do
echo Please enter a first name
read firstName
echo Please enter last name
read lastName
echo Please enter phone number
read phoneNumber
echo Please enter date of birth - format dd/mm/yyyy
read dob
echo "$firstName,$lastName,$phoneNumber,$dob" >> userBirthdays.csv
echo If you would like to add another person press 1 or enter 2 to proceed
read a
done
INPUT=./userBirthdays.csv
OLDIFS=$IFS
IFS=","
[! -f INPUT] & while read Name Surname Telephone DOB
do
birthMonth=${DOB:0:2}
birthDay=#10${DOB:3:2}
birthYear=${DOB:6:4}
currentDate=`date +%d/%m/%Y`
currentMonth=${currenDate:0:2}
currentDay=#10${currentDate:3:2}
currentYear=${currentDate:6:4}
if [[ "$currentMonth" -lt "$birthMonth" ]] || [[ "$currentMonth" -eq "$birthMonth" && "$((#10$currentDay))" -lt "$((#10$birthDay))" ]]
then
let Age=currentYear-birthYear-1
else
let Age=currentYear-birthYear
fi
echo "Name : $Name"
echo "Surname : $Surname"
echo "Telephone : $Telephone"
echo "DOB : $DOB"
echo "Age : $Age"
echo "##########################################"
done < $INPUT
IFS=$OLDIFS
echo $DATE
exit 0;
Thank you in advance
you need a space between between the [ and ! chars, i.e.
[ ! -f $INPUT ] && while read ....
#^-^--------^-^---^------------
Note that you almost certainly want two '&' chars, as in my correction.
Thanks to #GordonDavisson for another '$' ;-)
IHTH
Separate [ and ! with a space, so [ will be a command, and ! will be its first argument, as you meant them to be.
(Not sure there are no other problems).

Bash Shell Scripting - detect the Enter key

I need to compare my input with Enter/Return key...
read -n1 key
if [ $key == "\n" ]
echo "###"
fi
But this is not working.. What is wrong with this code
Several issues with the posted code. Inline comments detail what to fix:
#!/bin/bash
# ^^ Bash, not sh, must be used for read options
read -s -n 1 key # -s: do not echo input character. -n 1: read only 1 character (separate with space)
# double brackets to test, single equals sign, empty string for just 'enter' in this case...
# if [[ ... ]] is followed by semicolon and 'then' keyword
if [[ $key = "" ]]; then
echo 'You pressed enter!'
else
echo "You pressed '$key'"
fi
Also it is good idea to define empty $IFS (internal field separator) before making comparisons, because otherwise you can end up with " " and "\n" being equal.
So the code should look like this:
# for distinguishing " ", "\t" from "\n"
IFS=
read -n 1 key
if [ "$key" = "" ]; then
echo "This was really Enter, not space, tab or something else"
fi
I'm adding below code just for reference if someone will want to use such solution containing countdown loop.
IFS=''
echo -e "Press [ENTER] to start Configuration..."
for (( i=10; i>0; i--)); do
printf "\rStarting in $i seconds..."
read -s -N 1 -t 1 key
if [ "$key" = $'\e' ]; then
echo -e "\n [ESC] Pressed"
break
elif [ "$key" == $'\x0a' ] ;then
echo -e "\n [Enter] Pressed"
break
fi
done
read reads a line from standard input, up to but not including the new line at the end of the line. -n specifies the maximum number of characters, forcing read to return early if you reach that number of characters. It will still end earlier however, when the Return key is pressed. In this case, its returning an empty string - everything up to but not including the Return key.
You need to compare against the empty string to tell if the user immediately pressed Return.
read -n1 KEY
if [[ "$KEY" == "" ]]
then
echo "###";
fi
None of these conditions worked for me and so I've came up with this one:
${key} = $'\0A'
Tested on CentOS with Bash 4.2.46.

Resources