ファイル内の各行に対するawk forループ

ファイル内の各行に対するawk forループ

テキスト ファイルをループして、各行で名前、プロジェクト番号、電子メールのフィールドを取得し、送信する電子メール テンプレートで置き換える方法を理解する必要があります。

これは 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]

これは Reminder.email と呼ばれる電子メール テンプレートです。

Dear __FULLNAME__: 

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

Best Regards, 
CIS5027

したがって、このメールテンプレートのテキストファイルの各行で、次のフィールドを置き換える必要があります。フルネーム: 、 そしてプロジェクト対応する値を使用すると、最初の行に対して実行できますが、すべての行に対して実行することはできません。

これは私の脚本です

#

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

########

生成される出力は次のとおりです:

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

ご覧のとおり、フィールドは適切に置き換えられましたが、Jack Chen に対してのみ行われました。send.txt ファイルには 3 行あったため、上記のテンプレートの変更されたバージョンが 3 つあるはずです。

答え1

これに を使用する理由はありませんawk。シェルで直接実行できます。read一般的な形式は でread foo bar、最初のフィールドは として保存され$foo、各行の残りは として保存されます$bar。したがって、あなたの場合は、次のようになります。

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

IFS入力フィールド区切り文字で、 に設定すると、,コンマで区切られたフィールドを読み取ります。これにより、各フィールドを取得して変数に格納できます。fooと という2 つの追加変数を使用していることに注意してくださいbar。これは、各フィールドに独自の変数名が必要で、フィールドが 6 つあるためです。変数名を 4 つだけ指定した場合、4 番目 ( $e) にはフィールド 4 から最後のフィールドが含まれます。


さて、スクリプトには他にもさまざまな構文エラーがあります。まず、シェバン行が間違っています。 が必要です。と#! /bin/shの間に空白行を入れることはできません。また、 を割り当てるには#!/bin/sh出力コマンドを変数に割り当てるには、var=`command`またはvar=$(command)形式を使用する必要があります。それ以外の場合は、コマンド自体が文字列として変数に割り当てられ、その出力は変数に割り当てられません。最後に、printはあなたが考えているものとは異なります。探しているのはprintfまたはですecho。したがって、スクリプトを記述するより良い方法は次のようになります。

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

########

答え2

NR==1 条件を使用しましたNR==1{print $1}。つまり、 の最初の行が考慮されますsend.txt。2 行目を取得するには NR==2 条件を使用します。または、ループを使用してすべての行を調べます。

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

答え3

スクリプトを次のようにラップするといいでしょう

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

?

答え4

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

**s++ 各行を順に処理します **

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

関連情報