awk for loop para cada linha em um arquivo

awk for loop para cada linha em um arquivo

Preciso descobrir como percorrer um arquivo de texto e, para cada linha, pegar os campos name , project # e email e substituí-los em um modelo de email a ser enviado.

Então este é o arquivo de texto chamado 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]

e este é o modelo de email chamado Reminder.email:

Dear __FULLNAME__: 

This is a kindly reminder that our __Project__ meeting will be held on today. 

Best Regards, 
CIS5027

Portanto, para cada linha do arquivo de texto preciso substituir neste modelo de email os campos deNOME COMPLETO: , eProjeto. Com os valores correspondentes que posso fazer para a primeira linha, porém não consigo fazer para todas as linhas.

Este é o meu roteiro

#

!/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

########

Esta é a saída que ele produz:

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

Como você pode ver, os campos foram substituídos corretamente, mas apenas para Jack Chen. Havia 3 linhas no arquivo send.txt, portanto deve haver 3 versões modificadas do modelo acima.

Responder1

Não há razão para usar awkpara isso. Você poderia fazer isso diretamente no shell usandoread. O formato geral é read foo baraquele que salvará o primeiro campo como $fooe o restante de cada linha como $bar. Então, no seu caso, você faria algo como:

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

Este IFSé o Separador de campos de entrada que, quando definido como ,lê campos delimitados por vírgulas. Isso permite pegar cada campo e armazená-lo em uma variável. Observe que usei duas variáveis ​​extras fooe bar. Isso ocorre porque cada campo precisa de seu próprio nome de variável e você tem 6 campos. Se você fornecer apenas 4 nomes de variáveis, o quarto ( $e) conterá os campos do 4º ao último.


Agora, existem vários outros erros de sintaxe no seu script. Primeiro de tudo, a linha Shebang está errada, você precisa #! /bin/sh, não pode haver uma linha em branco entre o #!e o /bin/sh. Além disso, para atribuir osaídade um comando para uma variável, você precisa usar o formato var=`command`ou, de preferência var=$(command). Caso contrário, o próprio comando como uma string e não sua saída será atribuído à variável. Finalmente,printnão é o que você pensa que é. Você está procurando printfou echo. Então, a melhor maneira de escrever seu script seria:

#!/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

########

Responder2

Você usou NR==1 condição NR==1{print $1}. Isso significa que considerará a primeira linha do arquivo send.txt. Use a condição NR==2 para obter a segunda linha e assim por diante. OU use loop para percorrer todas as linhas como,

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

Responder3

talvez envolva seu script em algo como

for i in $(cat send.txt); do echo "line: $i"; done

?

Responder4

cat xtmp |  awk '{s++; do_aything_you_want_here }'

**s++ percorre cada linha **

cat xtmp
111
222
333
444

cat xtmp |  awk '{s++; print($1,"QQQ") }'
111 QQQ
222 QQQ
333 QQQ
444 QQQ

cat xtmp |  awk '{s++; print($1+3,"QQQ") }'
114 QQQ
225 QQQ
336 QQQ
447 QQQ

cat xtmp |  awk '{s++; for(i=1; i<=4 ; i++) print $1 }'  # this will repeat each line 4 time

cat tmp | awk '{s++; a=a+$1; print(s" "$1" "a)}' instead of a=a+$1 you can use a+=$1
1 111 111
2 222 333
3 333 666
4 444 1110

informação relacionada