why the sed command is not replacing the text - bash

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

Related

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

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

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!

Assign the output to variable in shell script

I am new to shell scripting and i am trying to assign the output of this line to a variable but all efforts are in vain.
var2=$(cat "filename")
var1=$(echo " $var2 +3 " | bc )
var2 is properly read from the file and also the output shows the value of the sumation, but the value is not assigned to the var1
ps : Filename contains a single entry which is a number
The code worked when i tried this
var3="$("echo " $var2 +3 " |bc)"
You are missing parenthesis
var2=$(cat "file")
var3=$(( var2 + 3 ))
echo $var3
Also you can try with expr
Something like this
var2=$(cat "filename")
var3=`expr $var2 + 3`
echo $var3
Here is a good answer
HIH

sed with loop to replace certain fields in a file with delimiter :

How should I use the sed command to replace certain fields with delimiter : and run a check to make sure that the user's input can be found within the file & if it can't be found it will loop again.
main_menu #function main_menu
echo "1) choice 1"
echo "2) choice 2"
read choice #read user choice on which choice he wants
if [ $choice -eq 1 ]
then
edit_item #function
read $choice_e #read input
grep -iqs "$choice_e: " Item.txt && echo "item found" #search file to find match
while [[ ! ${choice_e} =~ ^([Item.txt])$ ]]; do #loop to find if input matches search
echo "New Title: " #input new
read choice_n
sed -i 's/^/"$choice_n"\t/' Item.txt #edit the item
done
edit_item
else
echo "error" #return user to input again
fi
The invocation of sed is flawed because of the single quotes mixed with double quotes:
sed -i 's/^/"$choice_n"\t/'
The single quotes mean that the $ (and double quotes) are not interpreted by the shell. What you're probably after is:
sed -i "s/^/$choice_n\t/"
Without knowing exactly which shell and version of sed you're using, it isn't clear whether the \t sequence will be translated to a tab or not. In Bash, you could use the ANSI C Quoting mechanism:
sed -i "s/^/$choice_n"$'\t'/
I don't see where your 'delimiter :' is coming into play at all.

How do I read user input into a variable in Bash?

How do I read user input into a variable in Bash?
fullname=""
# Now, read user input into the variable `fullname`.
Use read -p:
# fullname="USER INPUT"
read -p "Enter fullname: " fullname
# user="USER INPUT"
read -p "Enter user: " user
If you like to get the user's confirmation:
read -p "Continue? (Y/N): " confirm && [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]] || exit 1
You should also quote your variables to prevent pathname expansion and word splitting with spaces:
# passwd "$user"
# mkdir "$home"
# chown "$user:$group" "$home"
Yep, you'll want to do something like this:
echo -n "Enter Fullname: "
read fullname
Another option would be to have them supply this information on the command line. Getopts is your best bet there.
Using getopts in bash shell script to get long and short command line options
Try this
#/bin/bash
read -p "Enter a word: " word
echo "You entered $word"
Also you can try zenity !
user=$(zenity --entry --text 'Please enter the username:') || exit 1
https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html
One line is read from the standard input, or from the file descriptor
fd supplied as an argument to the -u option, split into words as
described above in Word Splitting, and the first word is assigned to
the first name, the second word to the second name, and so on. If
there are more words than names, the remaining words and their
intervening delimiters are assigned to the last name.
echo "bash is awesome." | (read var1 var2; echo -e "Var1: $var1 \nVar2: $var2")
bash will be var1
is awesome will be var2
echo -e enable interpretation of backslash escapes from ubuntu manual.
so the full code can be:
echo -n "Enter Fullname: "
read fullname
echo "your full name is $fullname."
echo -n "test type more than 2 word: "
read var1 var2; echo -e
read var1 var2; echo -e "Var1: $var1 \nVar2: $var2")
Maximally portable (bash, zsh, ...):
printf "%s" "Enter fullname: "
read fullname
This is the most portable way to read with prompt. Methods such as read -p and echo -n are more likely to fail depending on the shell.

Resources