BASH - Print new entry to file with line number included - bash

I can't figure out how to add a line to a file then print that line only with the line number. Here is my current code which prints all lines:
printf "Would you like to add an entry to the file? Type yes or y? "
read addline
input=$addline
if [ $input = 'yes' ] || [ $input = 'y' ]
then
printf "Please enter a new name: First Last: "
read newname
printf "Please enter a new telephone number: xxx-xxx-xxxx: "
read phone
printf "Please enter a street address only: xxx Example Street: "
read street
printf "Please enter your birthdate: xx-xx-xxxx: "
read birth
printf "Please enter salary: xxxxxxx: "
read salary
echo -e "$newname:$phone:$street:$birth:$salary" >> datafile.txt
else
printf "\nYou did not type yes or y. Run the program again.\n"
exit
fi
printf "\nYour entry has been saved.\n"
sort -k2 $file | nl

You can use the -n option to grep to print a matching line along with its line number.
grep -n -F -x "$newname:$phone:$street:$birth:$salary" datafile.txt

Thanks to help from Barmar, I figured out my answer.
cat -n $file | grep "$newname:$phone:$street:$birth:$salary"
Thanks everyone.

Related

Bash Using variable names in sed to insert record

I'm trying to use sed in bash shell to insert a new row before row 1 with : as the Field Separator into an existing file but when I do it, it's printing the variable names instead of the values. Here's what I have. Sed seems to have quirky issues with variable names. Any suggestions?
#!/bin/bash
select CHOICE in add remove list find exit
do
echo "Pick a directory option: "
case $CHOICE in
add)
printf "What is the first name? "
read first
printf "What is the last name? "
read last
printf "What is the street address? "
read address
printf "What is the city? "
read city
printf "What is the State abreviation? "
read state
printf "What is the zip code? "
read zip
printf "What is the phone number? "
read phone
cat listing.txt | sed '1 i\ > "$first" ":" "$last" ":" "$address" ":" "$city" ":" "$state" ":" "$zip" ":" "$phone"' listing.txt;;
esac
done
I assume you're trying to edit listing.txt in place? Instead of the line starting cat listing.txt..., use this:
sed -i.bak "
1 i\\
$first : $last : $address : $city : $state : $zip : $phone
" listing.txt
This assumes that you didn't actually want quotes in the listing.txt file. It will also leave a listing.txt.bak as a backup to the edited file.

add specific string to a specific line at the end. -bash

I have a textfile(particulars.txt) which contains
personId,personName,employmentType
particulars.txt
1,jane,partTime
2,bob,fullTime
3,john,fullTime
How to do I make it such that if I key in the name of the worker, it will check whether that person is full time or part time worker and prompts the user to key in the salary and rewrite back to the file just for that person. I will explain in more details.
for example
Enter Name:jane
jane is a partTime staff
Enter Hourly Salary:10
so the textfile(particulars.txt) will now be
1,jane,partTime,10
2,bob,fullTime
3,johnfullTime
example two
Enter Name:bob
bob is a fullTime staff
Enter monthly Salary:1600
so the textfile(particulars.txt) will now be
1,jane,partTime,10
2,bob,fullTime,1600
3,john,fullTime
this is what I have
my code
#!/bin/bash
fileName="particulars.txt"
read -p "Enter name:" name
if grep -q $name $fileName; then
employmentType=$(grep $name $fileName | cut -d, -f4)
echo "$name is $employmentType" staff"
if [ $employmentType == "partTime" ]; then
echo "Enter hourly pay:"
read hourlyPay
#calculations for monthly salary(which I have not done)
elif [ $employmentType == "fullTime" ]; then
echo "Enter monthly salary:"
read monthlySalary
fi
else
echo "No record found"
fi
read -p "Press[Enter Key] to Contiune.." readEnterKey
I am only able to find which employment type does the person belongs to, but I am not sure of how/what should I do to add the salary at the end of the line just for that particular person. i have read up on sed , but I'm still confused on how to use sed to achieve my results and thus seeking help from you guys. Thanks in advance
Unless you need to do it in an interactive manner, you can say:
sed '/\bbob\b/{s/$/,1600/}' filename
This would add ,1600 to the line matching bob. Note that by specifying word boundaries \b, you'd ensure that the change is done only for bob, not abob or boba.
You can use the -i option to make the changes to the file in-place:
sed -i '/\bbob\b/{s/$/,1600/}' filename
EDIT: In order to use shell variable, use double quotes for the sed command:
sed "/\b$employeeName\b/{s/^$/,$monthlySalary/}" filename
I just modified your script.
#!/bin/bash
fileName="particulars.txt"
read -p "Enter name:" name
if grep -q $name $fileName; then
employmentType=$(grep $name $fileName | cut -d, -f3)
emp_name=$(grep $name $fileName | cut -d, -f2) # Getting emp name
emp_id=$(grep $name $fileName | cut -d, -f1) # Getting id
echo "$name is $employmentType staff"
if [ $employmentType == "partTime" ]; then
echo "Enter hourly pay:"
read hourlyPay
#calculations for monthly salary(which I have not done)
sed -i "s/^$emp_id.*$/&,$hourlyPay/g" $fileName # Modifying the file by using id.
elif [ $employmentType == "fullTime" ]; then
echo "Enter monthly salary:"
read monthlySalary
fi
else
echo "No record found"
fi
read -p "Press[Enter Key] to Contiune.." readEnterKey
I have added the below lines.
emp_id=$(grep $name $fileName | cut -d, -f1)
emp_name=$(grep $name $fileName | cut -d, -f2)
sed -i "s/^$emp_id.*$/&,$hourlyPay/g" $fileName

Command not found error

I've received an error command not found not sure what is wrong.
i think there is a problem with my code. i need user to enter the pay.
first user enter the ID, then the program will find the person with that ID.
then program will find the type of employee he is [salaried, or hourly]
then from there it will goes to if [$type="Salaried"] or' Hourly' code and
prompt user to key in the respective data
please advise how do i go about doing it?
payroll()
{
line=`grep -i "^${update_empID}," $data`
empID=`echo $line | cut -d "," -f1`
name=`echo $line | cut -d "," -f2`
job=`echo $line | cut -d "," -f3`
phone=`echo $line | cut -d "," -f4`
type=`echo $line | cut -d "," -f5`
clear
echo -e "Enter the pay"
echo -en "Enter ID: "
read empid_search
#Check if particular entry to search for existed to perform deletion
if [ `count_lines "^${empid_search},"` -eq 0 ]
then
echo "Error: This particular record does not exist!!"
else
echo "Please verify update of this employee's record: " #Prompt for confirmation of employee details
echo
echo "Employee's Details: "
locate_lines "^${empid_search}," #Find location of the entry
if [$type="Salaried"]
then
echo "$name is a Salaried"
echo "Enter Salary :"
read salary
echo "${empID},${name},${job},${phone},${Type},${salary}" >> tmpfile ; mv tmpfile $data
echo " particulars has been updated!!"
fi
else
echo "f"
fi
}
TEXT FILE
3,Frak,IT,9765753,Salaried
1,May,CEO,9789292,Salaried
5,Samy,Sales user,92221312,Commission
2,Orange,cleaner,935233233,Hourly
error:
line 371: [=Salaried]: command not found
This is the problem line:
if [$type="Salaried"]
You need to have spaces while comparing values in [ and ]:
if [ "$type" = "Salaried" ]

How to use sed to find the corresponding place in a text file and update it shell

Book name:author:price:Qty:Qty Sold
==================================
harry potter:james:12.99:197:101
===============================
I want to update the QTY which is the value of 197 in this case but i cant seems to be able to update the value with my program please help me as i have just started learning shell programming. Thanks
function update_qty_available
{
grep -c "$title:$author" BookDB.txt > /dev/null # Look for a line with matching values
if [ $? == 0 ];
then # If found then offer to change Qty
echo "Update Qty to what?"
read newQty
sed -i "s/\($title:$author\):[^:]:[^:]*:/\1:$newQty/" BookDB.txt
echo "Book's Qty has been updated successfully!"
fi
You're missing an asterisk after the first character class. And don't forget to expand the group.
Refactored to use grep -q; fix the if idiom; anchor the search to start of line; use read -p instead of a separate echo; capture the price inside the parens so that it's not lost; add the missing repeat in the regex; and add back the separator colon after the new qty value; also, add an else clause so that the function doesn't fail silently.
function update_qty_available
{
if grep -q "^$title:$author:" BookDB.txt
then
read -p "Update Qty to what?" newQty
sed -i "s/^\($title:$author:[^:]*\):[^:]*:/\1:$newQty:/" BookDB.txt
echo "Book's Qty has been updated successfully!"
else
echo "$0: BookDB.Txt: no '$title' by '$author'" >&2
fi
}
Here is how you'd do with awk:
Content of script.awk:
BEGIN {
FS=OFS=":"
printf "Enter the book's name: "
getline name < "-"
printf "Enter author's name: "
getline author < "-"
printf "Enter new quantity: "
getline newQty < "-"
}
$1==name && $2==author { $4=newQty }1
Run:
$ cat BookDB.txt
Book name:author:price:Qty:Qty Sold
==================================
harry potter:james:12.99:197:101
===============================
$ awk -f script.awk BookDB.txt
Enter the book's name: harry potter
Enter author's name: james
Enter new quantity: 5000
Book name:author:price:Qty:Qty Sold
==================================
harry potter:james:12.99:5000:101
===============================

grep exact integer match

read -p "Please enter ID: " staffID
id=$(grep -w "$staffID" record | cut -d ":" -f1 | sort -u );
echo $id
I have some issues with trying to grep the correct value from a file.
The following is stored in the record file.
12:Griffin:Peter:13:14:16
14:Griffin:Meg:19:19:10
10:Griffin:Loi:19:20:20
130:Griffin:Stewie:19:19:19
13:Wayne:Bruce:19:20:2
My first column stores the id which is always unique and is what I am looking for in grep. With the code above, I only want to find the unique ID which is entered by a user and is displayed on screen but my echo produces a blank value if I enter an ID of 13 when it should produce 13 obviously. Any ideas which would solve this?
#!/bin/bash
read -p "Please enter ID: " staffID
#your code was commented out
#id=$(grep -w "$staffID" record | cut -d ":" -f1 | sort -u );
id=$(grep -oP "^${staffID}(?=:)" record)
line=$(grep "^${staffID}:" record)
echo $id #use this line if you just want ID
echo $line #use this line if you want the line with given ID
see comments in codes
Note
I don't know the exact requirement, but I suggest that before do grep, check user input, if they inputted a valid id ([0-9]+) maybe? Because user could input .*
Seems adding a ^ to grep should solve your problem.
read -p "Please enter ID: " staffID
[[ "$staffID" =~ ^[0-9]+$ ]] || { echo "Enter only Numbers. Aborting" ; exit 2 ; }
id=$(grep -w "^$staffID" record | cut -d ":" -f1 | sort -u );
if [ "$id" == "" ]; then
echo "ID : Not found"
else
echo $id
fi
I have added a line to check that your input is a valid number.

Resources