このコマンドを使用して、以下の生ログから次の情報を抽出しました。
echo -e "Timestamp\t\tEmailTo:\t\tEmailFrom:\t\t\t\t\tIPAddress:\tErrorCodes:" && sed -n -e 's/.*\([0-9][0-9][0-9][0-9]\-[0-9][0-9]\-[0-9]*\) .*\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]*\).*/\1 \2 /p' logs
出力:
Timestamp EmailTo: EmailFrom: IPAddress: ErrorCodes:
2017-01-02 12:50:00
2017-01-02 13:10:25
ソースログ:
2017-01-02 12:50:00 1cNxNS-001NKu-9B == [email protected] R=dkim_lookuphost T=dkim_remote_smtp defer (-45) H=mta6.am0.yahoodns.net [98.138.112.38]: SMTP error from remote mail server after MAIL FROM:<[email protected]> SIZE=1772: 421 4.7.0 [TSS04] Messages from 192.168.1.269 temporarily deferred due to user complaints - 4.16.55.1; see https://help.yahoo.com/kb/postmaster/SLN3434.html
2017-01-02 13:10:25 1cNxhD-001VZ3-0f == [email protected] ([email protected]) <[email protected]> R=lookuphost T=remote_smtp defer (-45) H=mta7.am0.yahoodns.net [98.138.112.34]: SMTP error from remote mail server after MAIL FROM:<[email protected]> SIZE=87839: 500 5.9.0 [TSS04] Messages from 192.168.1.269 temporarily deferred due to user complaints - 4.16.55.1; see https://help.yahoo.com/kb/postmaster/SLN3434.html
ただし、必要な他の情報は抽出できません。
Timestamp EmailTo: mailFrom: IPAddress: ErrorCodes:
2017-01-02 12:50:00 [email protected] [email protected] 192.168.1.269 421 4.7.0
2017-01-02 13:10:25 [email protected] [email protected] 192.168.1.269 500 5.9.0
を使用してすべての情報を抽出する方法はsed
?
答え1
次の表現を試すことができますsed
。
sed -e 's/^\(.* .* \).* .*== \([^ ]* \).*MAIL FROM:<\([^ ]*\)> [^ ]* \([0-9 .]*\)\[.*Messages from \([^ ]*\).*$/\1\t\2\t\3\t\5\t\4/'
あなたの例では私にとって効果的でした。
説明する
式sed
には1つのコマンド()のみが含まれていますs/.../.../
。
最初の部分s///
:
'^\(.* .* \)' -- Timestamp, two first space-separated blocks of text, \1.
'.* .*== ' -- Uninteresting text after timestamp.
'\([^ ]* \)' -- Block of test between spaces, first email address, \2.
'.*MAIL FROM:<' -- Position before second email.
'\([^ ]*\)>' -- Second email addr, non-space characters, ended by '>', \3.
' [^ ]* ' -- SIZE=...:
'\([0-9 .]*\)\[' -- Error codes: digits, spaces and dots ended by '[', \4.
'.*Messages from ' -- Position before IP.
'\([^ ]*\)' -- Non-space characters, ended by space, IP. \5.
'.*$' -- Text before end of string, not interesting.
ご覧のとおり、これは元のログの直接的な説明であり、興味深いものではありません。
2番目の部分は、(タブ文字)を正しい順序で区切り記号として配置するs///
ことです。\N
\t
答え2
私はawkの経験はあまりありませんが、試してみたいです。私はあなたがどのように多くのログラインを取得したいのか分からないので、これは非常に脆弱だと思います。
とにかく、これはBEGIN
ブロックを使用して選択する変数を設定し、タイトルを表示する前に印刷する書式文字列を使用します。 TimeとEmailToは予測可能なので、3つの正規表現セット($1
、、$2
および$5
)の前に数値フィールドを使用できます。これは非常におおよその作業です。改善のためのどんな提案でも大変感謝します!
awk 'BEGIN {
from=""; ip=""; error=""; fstr="%-24s%-24s%-40s%-16s%s\n";
printf(fstr, "Timestamp:", "EmailTo:", "EmailFrom:", "IPAddress:", "ErrorCodes:");
}
{ for (i=6; i<NF; i++)
{
# From Address
if ($i ~ /FROM:<[^ ]*>/)
from=substr($i, 7, length($i)-7);
# Errors found in two adjacent fields.
if ($(i-1) ~ /[[:digit:]]{3}/ && $i ~ /[[:digit:]]\.[[:digit:]]\.[[:digit:]]/)
error=$(i-1) " " $i;
# From address after predictable string.
if ($(i-2) " " $(i-1) == "Messages from" && $i ~ /[[:digit:].]{7,15}/)
ip=$i;
}
printf(fstr, $1" "$2, $5, from, ip, error);
}' logs