複数行で一対となるデータを秀丸でgrepすNo.24669
s.k さん 08/03/18 18:54
 
sinitiです。

grepで複数行のあるキーワードの文字列を一対で抽出する方法を教えてください。

<やりたいこと>
sendmailのmaillogの中から、メールのFromのアドレスとToのアドレスが別のテキス
ト行で格納されたログから、
FromとTo(複数ある可能性あり、ccも同じ)を一対で抽出したのですがどなたか簡単
に抽出する方法を教えてください。

<sendmailのログの抽出方法>
tail -f /var/log/maillog > aa.log

上記のaa.logをクライアントマシンにftpで取得済です。
→下記のようなlog(例)です。
  アドレス等は可能しています。また、不要と思われる部分はカットしています。

@Mar 18 11:49:54 sss sendmail[19536]: m2I2nre19536: from=<aa@bbb.com>, size
=58668, ・・・
AMar 18 11:49:54 sss sendmail[19539]: m2I2nre19536: to=<cc@ddd.com>,<ee@fff.
com>, ctladdr=<ff@ggg.com> (725/725), delay=00:00:01,

<grepでやりたいこと>
 上記の、Aの行の「@ddd.com>」あるいは「@fff.com>」等を、指定の文字列で抽出
した行の「m2I2nre19536」という文字列をキーにして、このキーが同じ行の「from=<
aa@bbb.com>」を下記のように抽出したい。

cc@ddd.com,aa@bbb.com
ee@fff.com,aa@bbb.com
ff@ggg.com,aa@bbb.com

→要するに、いろいろなメールアドレスから(From)から指定したメールアドレスに(T
o)に来たメールのFrom対Toのアドレスを作成したいのです。

[ ]
RE:24669 複数行で一対となるデータを秀丸No.24671
秀丸担当 さん 08/03/19 09:46
 

>@Mar 18 11:49:54 sss sendmail[19536]: m2I2nre19536: from=<aa@bbb.com>, size
>=58668, ・・・
>AMar 18 11:49:54 sss sendmail[19539]: m2I2nre19536: to=<cc@ddd.com>,<ee@fff.
>com>, ctladdr=<ff@ggg.com> (725/725), delay=00:00:01,
>
><grepでやりたいこと>
> 上記の、Aの行の「@ddd.com>」あるいは「@fff.com>」等を、指定の文字列で抽出
>した行の「m2I2nre19536」という文字列をキーにして、このキーが同じ行の「from=<
>aa@bbb.com>」を下記のように抽出したい。
>
>cc@ddd.com,aa@bbb.com
>ee@fff.com,aa@bbb.com
>ff@ggg.com,aa@bbb.com

こういったことをするには、簡単にgrepではできないです。
マクロで、ある程度複雑な処理を作る必要があります。
メールアドレスの検索、from=やto=の検索、キーの照合など、けっこう複雑なこ
とになると思います。
どなたか作ってくれるといいのですが…

もし作ってくれる方がおられる場合、fromとtoは必ず別の行にあるのかどうか、
同じキーの行は隣接しているのか、またfromが必ず先にあるのか、キーの書き方
の特徴、"to="と"ctladdr="だけなのか、"cc="や"bcc="はあるのかなど、より詳
しい条件がわかると作りやすいかもしれません。

[ ]
RE:24669 複数行で一対となるデータを秀丸No.24672
ENCODINGSHIFTJIS さん 08/03/19 10:54
 
>ff@ggg.com,aa@bbb.com
to= の所にありませんが

[ ]
RE:24672 複数行で一対となるデータを秀丸No.24673
s.k さん 08/03/19 12:02
 
>>ff@ggg.com,aa@bbb.com
>to= の所にありませんが

ctladdr=< 部分のアドレスもとりたいです。

[ ]
RE:24671 複数行で一対となるデータを秀丸No.24674
s.k さん 08/03/19 12:30
 
秀まるお2さん

コメントありがとうございます。

>
>>@Mar 18 11:49:54 sss sendmail[19536]: m2I2nre19536: from=<aa@bbb.com>, size
>>=58668, ・・・
>>AMar 18 11:49:54 sss sendmail[19539]: m2I2nre19536: to=<cc@ddd.com>,<ee@fff.
>>com>, ctladdr=<ff@ggg.com> (725/725), delay=00:00:01,
>>
>><grepでやりたいこと>
>> 上記の、Aの行の「@ddd.com>」あるいは「@fff.com>」等を、指定の文字列で抽出
>>した行の「m2I2nre19536」という文字列をキーにして、このキーが同じ行の「from=<
>>aa@bbb.com>」を下記のように抽出したい。
>>
>>cc@ddd.com,aa@bbb.com
>>ee@fff.com,aa@bbb.com
>>ff@ggg.com,aa@bbb.com
>
>こういったことをするには、簡単にgrepではできないです。

やはりそうですか?

>マクロで、ある程度複雑な処理を作る必要があります。
>メールアドレスの検索、from=やto=の検索、キーの照合など、けっこう複雑なこ
>とになると思います。
>どなたか作ってくれるといいのですが…

私もマクロの作成知識があれば自分で作りたいのですが、
その知識が無いため、どなたかご協力いただける人がいれば感謝です。

>
>もし作ってくれる方がおられる場合、fromとtoは必ず別の行にあるのかどうか、
>同じキーの行は隣接しているのか、またfromが必ず先にあるのか、キーの書き方
>の特徴、"to="と"ctladdr="だけなのか、"cc="や"bcc="はあるのかなど、より詳
>しい条件がわかると作りやすいかもしれません。

すみません。説明不足で申し訳ありませんでした。
多少補足します。
Q1)fromとtoは必ず別の行にあるのかどうか
 Ans1)見た限り、別の行にあります。サンプルで掲載したとおりです。
 @、Aの順番で別の行です。
 また、toより前にfromがあります。

Q2)同じキーの行は隣接しているのか
 Ans2)隣接(前後)していそうです。隣接している前提で結構です。

Q3)またfromが必ず先にあるのか
 Ans3)ログを見ると先にFromがあり、後にToがあります。

Q4)キーの書き方の特徴
 Ans4)これだけはどのような規則で発生させているのかは不明です。
   ただし、以下の順番に並んでいます。
Mar 19 09:24:03 xxx sendmail[3569]: m2J0O3e03569: from=<xxx@bbb.com>,・・
Mar 19 09:24:04 xxx sendmail[3571]: m2J0O3e03569: to=<xxx@ddd.com>, ctladdr=
<xxx@fff.com> ・・・

Q5)"to="と"ctladdr="だけなのか、"cc="や"bcc="はあるのかなど
 Ans5)to=からfromを探して欲しいです。
   どうも、ctladdr= はfromと同じですので、無視で結構です。
   cc=やbcc=は無いみたいです。?

最後に以下も条件にほしいです。
Ans6)と=の行が複数ある場合があります。(MLの場合みたいです)

よろしくお願いします。

[ ]
RE:24673 複数行で一対となるデータを秀丸No.24675
ENCODINGSHIFTJIS さん 08/03/19 16:33
 
from= と to= の行を結合するのは

 setcompatiblemode 0x0F;
 searchdown "from=<" , casesense, hilight;
 if( ! result )  beep;
 beginsel;
 searchdown " " , casesense, hilight;
 if( ! result )  beep;
 cut;
//
 setcompatiblemode 0x0F;
 searchup ":" , casesense, hilight;
 if( ! result )  beep;
 beginsel;
 searchup " " , casesense, hilight;
 if( ! result )  beep;
 right;
 $ID=gettext(seltopx,seltopy,selendx,selendy); // macro の知識が必要なのはこ
こだけ
 searchdown $ID , casesense, hilight;
 if( ! result )  beep;
 searchdown ":", casesense, hilight;
 right;
 escape;  paste;

とか、手操作に 一行追加しました。結果の細部は要調整 、結合一回分です
この後は、不要部を取り除いて、  ABBBB から AB、AB、AB を発生させる ですね。
複数 段階の 操作も 部分ごとに 解決してください。

[ ]
RE:24675 複数行で一対となるデータを秀丸No.24676
秀丸担当 さん 08/03/20 10:14
 
せっかくなので作ってみました。
条件を元に多少はしょっているので、もしかしたら漏れがあるかもしれませんが。
キーは半角英数字のみ([a-z0-9]+)であると勝手に解釈しました。
ログファイルを開いている状態で実行します。
grepのように複数ファイルを一括で処理するようにはしてないです。

disabledraw;
selectall;
copy;
newfile;
disabledraw;
paste;
gofiletop;
$mailstr="[!$%&*\-./0-9;?a-z^_~=]+@[\\-.0-9a-z_~]+\\.[\\-.0-9a-z_~]+";
#lineEnd = linecount2;
while(1){
  searchdown $mailstr, regular, nocasesense;
  if( !result ) break;
  if( lineno >= #lineEnd ) break;
  $to = gettext(foundtopx,foundtopy,foundendx,foundendy);
  #colNext = xtocolumn(foundendx,foundendy);
  #lineNext = ytolineno(0,foundendy);
  while(1){
    searchup "=<";
    if( !result ) break;
    if( ytolineno(0,foundtopy) != #lineNext ) break;
    wordleft;
    if( gettext(x,y,foundtopx,foundtopy) != "to" ) {
      break;
    }
    searchup "\\]: [a-z0-9]+: ", regular, nocasesense;
    if( !result ) break;
    $key = gettext(foundtopx,foundtopy,foundendx,foundendy);
    searchup $key + "from=<";
    if( !result ) break;
    #xFrom = foundendx;
    #yFrom = foundendy;
    searchdown $mailstr, regular, nocasesense;
    if( !result ) break;
    if( #xFrom != foundtopx || #yFrom != foundtopy ) break;
    $from = gettext(foundtopx,foundtopy,foundendx,foundendy);
    gofileend;
    insert $to + "," + $from + "\n";
    break;
  }
  movetolineno #colNext+1, #lineNext;
  title str(lineno) + "/" + str(#lineEnd);
}
movetolineno 1, #lineEnd;
beginsel;
gofiletop;
delete;
endmacro;

[ ]
RE:24676 複数行で一対となるデータを秀丸No.24680
s.k さん 08/03/22 14:51
 
秀丸担当殿

>せっかくなので作ってみました。
>条件を元に多少はしょっているので、もしかしたら漏れがあるかもしれませんが。
>キーは半角英数字のみ([a-z0-9]+)であると勝手に解釈しました。
>ログファイルを開いている状態で実行します。
>grepのように複数ファイルを一括で処理するようにはしてないです。

連絡が遅くなりましたが、
期待通りのマクロでした。
ありがとうございました。

[ ]