Shell script - Replace just part of a single line in a file.....

Hey guy's....

I new here,
But im working on a school project, and I am not really good at programming. In fact, this is the only programming class that I need because programming is not what I am majoring in.

But I have everything done in this shell script except for this last part.....

Basically I have a file of an employee record book,
Formatted like so:
Firstname Lastname Phone OnCallDay

ex:
Henry Test 000-000-0000 Wed

There are more people in my file though. I have a shell script made to make changes to the record book. (add, delete records). But I need to add to my shell script, to let a person change a record's on call day.

It must only prompt the user for the person's name, and then the new on call day. It can not ask for the user's old on call day. So I really have no idea I would search for just a part of a line. Like is there is some way to just edit the last 3 characters of a given line?

Also two people cannot have the same on call day. (I have already figured this part out)

Here is that part of the script so far:

echo "Enter the name of the employee, to change their on-call day: "
read name
echo "enter new on call day: "
read newday
days=`grep $newday phonebook | wc -l`   #This is to check availability day
if [ $days -ne 0 ]
then
   echo "Sorry there is already an employee on call for that day"
   exit
else
   and this is where I would need to somehow pull the previous day (Mon,wed,Tue,Thu,Fri,Sat,Sun) out of a line and change it to the $newday. But I have no idea where to start

I know that I would start here by doing a grep to search for the person's line. But then I need to change the 3char on-call day of that line.....

Could anyone help me figure this last part out?
Any help would be greatly appreciated.....
Thanks a lot

Use awk:-

awk -v N=$name -v D=$newday '$0 ~ N { $NF=D; print $0; } ' record_book_file

You can used 'sed' to update the 'day' on the record, for example:

$ name="Henry Test"

$ day="FRI"

$ echo 'Henry Test 000-000-0000 Wed' | sed "s/^\($name [0-9]\{1,3\}-[0-9]\{1,3\}-[0-9]\{1,4\}\) .../\1 $day/"
Henry Test 000-000-0000 FRI

Thanks for the reply, :slight_smile:

That seems to do exactly what I wan't, it's just not writing it to the file (my file named phonebook).

echo "Enter the name of the employee, to change their on-call day: "
read name
echo "enter new on call day: "
read newday
days=`grep $newday phonebook | wc -l`   #This is to check availability day
if [ $days -ne 0 ]
then
   echo "Sorry there is already an employee on call for that day"
   exit
else
   awk -v N=$name -v D=$newday '$0 ~ N { $NF=D; print $0 } ' phonebook
fi
echo "Success";;

I changed the on call day from Wed to Sun and it came up and showed
Henry Test 000-000-0000 Sun
But it didn't write it to the file. Im not familiar with awk, but could I make the awk line a variable to use to add to the file?
like:
add = awk -v N=$name ..... etc
echo "$add" >> phonebook

or would that not work?

To write result to a file:-

awk -v N=$name -v D=$newday '$0 ~ N { $NF=D; print $0 } $0 !~ N { print $0 } ' phonebook > tmp
# mv tmp phonebook

Note: I am writing result to a temporary file: tmp and then I am renaming file: tmp back to file: phonebook. But I have commented out that line because first you have to check and verify if file: tmp is having desired result. If yes, then please un-comment it. I hope this helps.

Ok that makes sense now. Yep that works.....
Thanks a lot!.... that was killing me

One last question, Say I have my record book formatted right now. Is it hard to make awk format/space each part out?

Like have the firstname span to 10 spaces, the last name span to 10 spaces etc?

I was able to do that earlier in my script file (the part where you could add a user to the file) by using:

first=$(printf "%-16s" $first)
last=$(printf "%-13s" $last)

So that way multiple different length names will space out the same....
Ex:
Henry Test 000-000-0000 Sun
Timothy Lastname 000-000-0000 Sun

EDIT: Once again, thank you!

Adjust the length as per your requirement:-

awk ' { printf "%s %-10s %s %s\n", $1, $2, $3, $4 } ' phonebook > tmp
mv tmp phonebook

You are a genius..... that works!

I have a little bit of a header going on before my file

ex:
-------------------
Record File
-------------------
first | last | phone | day
------------------------
Henry Test 000-000 Sun

The formatting seems to be kind of messing with my header though. Other than that the spacing worked perfectly.

Maybe I can just separate the header and results into two files, and then append them at the end when the shell script is finished. That should solve that.

If header is first 4 lines, then you can use following option to direct awk to ignore header for formatting:-

awk ' NR<=4 { print $0 } NR>4 { printf "%s %-10s %s %s\n", $1, $2, $3, $4 } ' phonebook > tmp
1 Like

That's it!

It works flawlessly now. Thank you!

We didn't even cover awk and it wasn't in the book. But, I had everything else done, and could not find any way to do that last part, so that is what he is getting....

Thanks a lot for the quick help :D:)