awk for loop for each line in a file
Solution 1
There is no reason to use awk
for this. You could do it directly in the shell using read
. The general format is read foo bar
which will save the first field as $foo
and the rest of each line as $bar
. So, in your case, you would do something like:
while IFS="," read p n l foo bar e; do
sed -e "s/__FULLNAME__:/\ $n $l :/g;s/__Project__/\ $p /g" Reminder.email;
done < file
The IFS
is the Input Field Separator which, when set to ,
reads comma delimited fields. This lets you take each field and store it in a variable. Note that I used two extra variables foo
and bar
. This is because each field needs its own variable name and you have 6 fields. If you only give 4 variable names, the 4th ($e
) will contain the fields 4 through last.
Now, there are various other syntax errors in your script. First of all the shebang line is wrong, you need #! /bin/sh
, there can't be a blank line between the #!
and the /bin/sh
. Also, in order to assign the output of a command to a variable, you need to use the var=`command`
or, preferably var=$(command)
format. Otherwise, the command itself as a string and not its output is assigned to the variable. Finally, print
is not what you think it is. You are looking for printf
or echo
. So, a better way to write your script would be:
#!/bin/sh
date=$(date "+%m/%d/%y")
echo $date
## The following line is to scan a file called Event-member.data
## and return any lines with todays date and save them to a file
## called sendtoday.txt
grep -n $(date +"%m,%d") Event-member.data > sendtoday.txt
## The following line is to remove the first to characters of the file
## created above sendtoday.txt and output that to a file called
## send.txt.
## I rewrote this to avoid the useless use of cat.
sed 's/^..//' sendtoday.txt > send.txt
## This is where you use read
while IFS="," read p n l foo bar e; do
sed -e "s/__FULLNAME__:/\ $n $l :/g;s/__Project__/\ $p /g" Reminder.email > sendnow.txt
cat sendnow.txt
## This is where you need to add the code that sends the emails. Something
## like this:
sendmail $e < sendnow.txt
done < send.txt
exit 0
########
Solution 2
You have used NR==1 condition NR==1{print $1}
. That means it will consider the first line of send.txt
. Use NR==2 condition to get for 2nd line and so on. OR use loop to go through all the lines like,
while read line
do
p=`echo $line | awk -F '.' '{print $1}'`
n=`echo $line | awk -F '.' '{print $2}'`
l=`echo $line | awk -F '.' '{print $3}'`
e=`echo $line | awk -F '.' '{print $1}'`
sed -e "s/\__FULLNAME\__:/\ $n $l :/g;s/\__Project__/\ $p /g" Reminder.email > sendnow.txt
done<send.txt
Solution 3
maybe wrap your script in something like
for i in $(cat send.txt); do echo "line: $i"; done
?
Related videos on Youtube
S0urc3
Updated on September 18, 2022Comments
-
S0urc3 over 1 year
I need to figure out how to get loop through a text file and for every line take the fields of name , project #, and email, and replace them in a email template to be sent out.
So this is the text file called send.txt:
Project 1,Jack,Chen,06,12,[email protected] Project 2,Emily,Weiss,06,12,[email protected] Project 3,Mary,Gonzalas,06,12,[email protected]
and this is the email template called Reminder.email:
Dear __FULLNAME__: This is a kindly reminder that our __Project__ meeting will be held on today. Best Regards, CIS5027
So for every line in the text file I need to replace in this email template the fields of FULLNAME: , and Project . With the corresponding values which I can do for the first line, however I cannot do it for every line.
This is my script
# !/bin/sh #Start your code from here date= date "+%m/%d/%y" print $date #The following line is to scan a file called Event-member.data and return any lines with todays date and save them to a file called sendtoday.txt grep -n $(date +"%m,%d") Event-member.data > sendtoday.txt #The following line is to remove the first to characters of the file created above sendtoday.txt and output that to a file called send.txt. cat sendtoday.txt | sed 's/^..//' > send.txt #This is where im having trouble. When storing the values for the variables below of name, email, project #. The value of NR==1 thus it never goes through the rest of the lines. I've tried different solutions but none seem to work. p=$(awk -F ',' 'NR==1{print $1}' send.txt) n=$(awk -F ',' 'NR==1{print $2}' send.txt) l=$(awk -F ',' 'NR==1{print $3}' send.txt) e=$(awk -F ',' 'NR==1{print $6}' send.txt) echo $p $n $l $e #This part is to replace the values in the email template using sed and save the modified template as sendnow.txt. sed -e "s/__FULLNAME__:/\ $n $l :/g;s/__Project__/\ $p /g" Reminder.email > sendnow.txt cat sendnow.txt #Yet to be written ... send out modified email templates. exit 0 ########
This is the output it produces :
06/12/14 Project 1 Jack Chen [email protected] Dear Jack Chen : This is a kindly reminder that our Project 1 meeting will be held on today. Best Regards, CIS5027
As you see it did properly replace the fields but only for Jack Chen. There were 3 lines in the send.txt file so there must be 3 modified versions of the above template.
-
Jasper almost 10 yearsstackoverflow.com/questions/15945302/… this seems to solve your problem.
-
-
terdon almost 10 years-1. Very bad idea I'm afraid. 1) That reads the entire line (kind of, see the next point) into
$i
which does not help the OP. 2) You never want to dofor i in $(cat file)
, you should always usewhile read i; do ... ; done < file
instead. With the for loop, the line will be split on whitespace so$i
will beProject
, then1,Jack,Chen,06,12,[email protected]
for the first line. 3) This doesn't answer the question in any case since you don't address the actual issue the OP had. -
S0urc3 almost 10 yearsThis works like clockwork. Thank you so much for your help. I think this is the most concise answer. I will be seeking your help again in the future :-) .
-
S0urc3 almost 10 yearsThis is the approach I wanted to take but couldn't get this to work out. The above IFS approach works good though. Thanks for your input. Ill try to test this again.