

環境: CentOS 6.9

お世話になります。  
以前こちらで[awkを使用して指定期間内のメールログを抽出する方法](https://ja.stackoverflow.com/questions/37440/)をご教授いただき、大変参考なりました。

ここから更に改良できれば思っており色々と考えておりましたが自分だけでは上手くいかず、再度こちらから皆様のご意見をいただければと質問させていただきました。

メールログのサンプルはこちらとなります。  
正常送信された場合のものとバウンスになった場合のものとなります。  
送信先によって若干異なりますが、基本的にはこのような形式です。  
例としてSoftBank(i.softbank.jp)に送信した際のものです。  
ちなみにご覧の通りAWSにて送信しております。

[code]

    May 10 00:00:00 ip-172-31-21-151 mail/smtpd[1439]: B670861CA0: client=ip-172-31-38-47.ap-northeast-1.compute.internal[172.31.38.47]
    May 10 00:00:00 ip-172-31-21-151 mail/cleanup[1477]: B670861CA0: message-id=<hogehoge@example.com>
    May 10 00:00:00 ip-172-31-21-151 mail/qmgr[1431]: B670861CA0: from=<hogehoge@example.com>, size=494, nrcpt=1 (queue active)
    May 10 00:00:00 ip-172-31-21-151 mail/smtp[1459]: B670861CA0: to=<hogehoge@i.softbank.jp>, relay=msv.softbank.jp[117.46.9.104]:25, delay=0.8, delays=0.06/0/3.1/0.6, dsn=2.0.0, status=sent (250 Message received: 20180510111628949.MPQS.14641.ebmky105sc.i.softbank.jp@ebmky105sb.mailsv.softbank.jp)
    May 10 00:00:00 ip-172-31-21-151 mail/qmgr[1431]: B670861CA0: removed
    
    May 10 00:00:00 ip-172-31-21-151 mail/smtpd[8874]: 5564561CB8: client=ip-172-31-38-47.ap-northeast-1.compute.internal[172.31.38.47]
    May 10 00:00:00 ip-172-31-21-151 mail/cleanup[8877]: 5564561CB8: message-id=<QUdsjiAFHF@OzemvwHngZ>
    May 10 00:00:00 ip-172-31-21-151 mail/qmgr[8873]: 5564561CB8: from=<hogehoge@example.com>, size=442, nrcpt=1 (queue active)
    May 10 00:00:00 ip-172-31-21-151 mail/smtp[8896]: 5564561CB8: to=<hogehoge@i.softbank.jp>, relay=msv.softbank.jp[117.46.7.40]:25, delay=1.1, delays=0.01/0/1/0.06, dsn=5.0.0, status=bounced (host msv.softbank.jp[117.46.7.40] said: 550 Invalid recipient: <hogehoge@i.softbank.jp> (in reply to RCPT TO command))
    May 10 00:00:00 ip-172-31-21-151 mail/bounce[8906]: 5564561CB8: sender non-delivery notification: 6B19061CB3
    May 10 00:00:00 ip-172-31-21-151 mail/qmgr[8873]: 5564561CB8: removed
    
[/code]

以前ご教示いただいた内容を参考に現在は以下のように出力しております。  
（例としてSoftbank系のtoを抽出した場合）

[code]

    #!/bin/bash
    
    filename='filename.csv'
    nowtime=`date +%s`
    updatetime=`date +%s -r $filename`
    thisyear=`date +%Y`
    thismonth=`date +%m`
    
    localstr=`date "+%D %T"`
    gmstr=`date "+%D %T" -u`
    localtime=`date -d "$localstr" +%s`
    gmtime=`date -d "$gmstr" +%s`
    timediff=$(($localtime - $gmtime))
    
    cat /var/log/maillog | awk -F - -v nowtime="$nowtime" -v updatetime="$updatetime" \
        -v thisyear="$thisyear" -v thismonth="$thismonth" \
        -v timediff="$timediff" '{
        m = substr($1, 1, 3)
        mon = (index("JanFebMarAprMayJunJulAugSepOctNovDec", m) + 2) / 3
        year = mon <= thismonth ? thisyear : thisyear - 1
        day = substr($1, 5, 2)
        hh = substr($1, 8, 2)
        mm = substr($1, 11, 2)
        ss = substr($1, 14, 2)
    
        if (mon < 3) {mon += 12; year--}
        epochtime = (365 * year + int(year / 4) - int(year / 100) + int(year / 400) \
            + int(306 * (mon + 1) / 10) - 428 + day - 719163) * 86400 \
            + (hh * 3600) + (mm * 60) + ss - timediff;
        } updatetime < epochtime && epochtime <= nowtime' 
        |grep -e 'to=<.*@i.softbank.jp>\|to=<.*@softbank.ne.jp>\|to=<.*vodafone.ne.jp>' 
        |grep -v 'discard' |sed -e 's/(250.*)//' 
        |awk '{if ($12 == "status=deferred") print $1,$2,$3,$7,$12; else if ($16 == 550) print $1,$2,$3,$7,$12,$16,$23; else print $1,$2,$3,$7,$12,$16}' 
        |sed -e 's/to=<//' |sed -e 's/>,//' 
        |sed -e 's/status=//' 
        |awk '{print($1,$2,$3 "," $4 "," $5 "," $6 "," $7)}' > $filename
    
[/code]

日時,送信先メールアドレス(to),status,エラーコード,エラー種別

カンマで区切りCSVファイルとして出力しています。

[code]

    May 8 00:00:00,to@hogehoge.com,sent,,
    May 8 00:01:00,to@hogehoge.com,bounced,550,DATA
    May 8 00:02:00,to@hogehoge.com,bounced,550,RCPT
    
[/code]

こちらに加えて送信元メールアドレス(from)を追加したいと思っております。

同様の条件でtoのキューIDを抽出し、それを元にfromを抽出、  
最終的には上記にfromが追加された状態で出力できればと考えております。

出力したい具体例は以下の通りです。

[code]

    May 8 00:00:00,to@hogehoge.com,sent,,,from@example.com
    May 8 00:01:00,to@hogehoge.com,bounced,550,DATA,from@example.com
    May 8 00:02:00,to@hogehoge.com,bounced,550,RCPT,from@example.com
    
[/code]

以上、何卒よろしくお願いいたします。


CC BY-SA 4.0
2018-05-08T02:09:33.527
43851
2018-05-10T14:11:07.610
2018-05-10T13:34:22.777
25016
25016
question
bash sh awk
maillogを解析して一行に集約して出力する方法について


基本的にはキューのIDをキーにして集計すればよいのですが、

  * キューと発信者は1対1だが、宛先は1対Nとなる
  * 相手先が400番台のエラーでメールを受け取らなかった場合、キューが長期間残存し、繰り返しログに出現する。
  * キューのIDは再利用される可能性がある

という事情があり、集計は割と大変です。それなりの言語でそれなりの長さのプログラムを作る必要があります。


CC BY-SA 4.0
2018-05-10T14:11:07.610
43907
2018-05-10T14:11:07.610
5793
43851
answer