awk for loop para cada línea en un archivo

awk for loop para cada línea en un archivo

Necesito descubrir cómo recorrer un archivo de texto y, para cada línea, tomar los campos de nombre, número de proyecto y correo electrónico, y reemplazarlos en una plantilla de correo electrónico para enviar.

Este es el archivo de texto llamado 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]

y esta es la plantilla de correo electrónico llamada Reminder.email:

Dear __FULLNAME__: 

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

Best Regards, 
CIS5027

Entonces, para cada línea del archivo de texto necesito reemplazar en esta plantilla de correo electrónico los campos deNOMBRE COMPLETO: , yProyecto. Con los valores correspondientes puedo hacerlo para la primera línea, sin embargo no puedo hacerlo para cada línea.

Este es mi guión

#

!/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 es la salida que produce:

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 puede ver, reemplazó correctamente los campos, pero solo para Jack Chen. Había 3 líneas en el archivo send.txt, por lo que debe haber 3 versiones modificadas de la plantilla anterior.

Respuesta1

No hay ninguna razón para usarlo awkpara esto. Podrías hacerlo directamente en el shell usandoread. El formato general es read foo barque guardará el primer campo como $fooy el resto de cada línea como $bar. Entonces, en tu caso, harías 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

Es IFSel separador de campos de entrada que, cuando se configura para ,leer campos delimitados por comas. Esto le permite tomar cada campo y almacenarlo en una variable. Tenga en cuenta que utilicé dos variables adicionales fooy bar. Esto se debe a que cada campo necesita su propio nombre de variable y tienes 6 campos. Si solo proporciona 4 nombres de variables, el cuarto ( $e) contendrá los campos del 4 al último.


Ahora, hay varios otros errores de sintaxis en su secuencia de comandos. En primer lugar, la línea shebang es incorrecta, es necesario #! /bin/sh, no puede haber una línea en blanco entre #!y /bin/sh. Asimismo, para asignar elproducciónde un comando a una variable, necesita usar el formato var=`command`o, preferiblemente var=$(command). De lo contrario, el comando en sí como una cadena y no su salida se asigna a la variable. Finalmente,printno es lo que crees que es. Estás buscando printfo echo. Entonces, una mejor manera de escribir tu guión sería:

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

########

Respuesta2

Ha utilizado la condición NR==1 NR==1{print $1}. Eso significa que considerará la primera línea de send.txt. Utilice la condición NR==2 para obtener la segunda línea y así sucesivamente. O use el bucle para recorrer todas las líneas 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

Respuesta3

tal vez envuelva su guión en algo como

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

?

Respuesta4

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

**s++ pasa por cada línea**

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

información relacionada