• ベストアンサー

大量のメールの文字数を一気に数える

200通くらいのメールがあって、 それぞれのメールが何文字かをカウントして一気に集計したいのですが、bash などのスクリプトで便利な方法はないでしょうか?なにしろメールの数が大量なので、、、 数えたいのは、一通当たり平均何文字か、です。 本当は、メール本文の文字数が良いですが、(メールヘッダも含めた)バイト数でも良いです。 メールは Solaris のサーバ上で読んでいるので、原始的な mail コマンドでも読めるし、もちろん、pop クライアントでとりこんでもいいです。

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4900/10358)
回答No.4

#1,#3です。 >「先頭がFromの行、から、先頭が行末(空行)の行まで」 >となるのでしょうか? >このばあい、本文中に空行があると、そこをメールの終わりの行と勘違いしてしまわないでしょうか? /^From /の行から、次のパターン(空行)が最初に現れた行(ヘッダと本文の区切り行)までが範囲になり、それ(ヘッダ部分)が削除(d)されます。したがって本文中の空行はパターンにマッチしません。さらにさっきの範囲の次の行からまた/^From /が探され、繰り返します。これですべてのメールのヘッダが削除されることになり、残ったのが本文です。 以下、unix-mailbox形式の簡単な解説: 各メールの先頭のFrom 行はunix-from行と呼ばれ、本来 From someone@somewhere Mon Jan 1 00:00:00 2004 のような書式のアドレスと日時が必要なのですが、そこまでチェックしていないメーラーもあるようなので、今回の正規表現はサボってます。また2通目以降のunix-from行の前には空行が必要ですが、それのチェックもサボってます。まあ、大丈夫でしょう。 本文中に/^From /のパターンがあればunix-from行と間違わないためにメールボックス格納時に行頭に > が挿入されるので本文中に/^From /のパターンが現れることは無いはずです。ただし、Content-Length: で本文長を示しているケースでは本文の終わりが/^From /のパターンによらずに分かるので > の挿入がされないケースがあり、/^From /でメールの区切りが分からないので最初に聞きました。 なお、bash では、 exec 3<>/dev/tcp/HOSTNAME/110 とやれば、 read a <&3 echo xxxx >&3 で、POP3サーバーと通信できるので、#2の方の方法も使えます。メールボックスを直接読めるなら読んだほうがずっと楽ですが、興味があればトライしてみては?

white-tiger
質問者

お礼

ありがとうございます。 とても分かりやすかったです。 また、unix-mailbox の説明も、へえ、でした。 大変勉強になりました!

その他の回答 (3)

  • notnot
  • ベストアンサー率47% (4900/10358)
回答No.3

#1です。 >Content-Length: ヘッダはないようです。 そうすると、 メールの数は、grep '^From ' $MAIL | wc -l 本文のバイト数は、sed '/^From /,/^$/d' $MAIL | wc -c で分かります。 N=`grep '^From ' $MAIL | wc -l` B=`sed '/^From /,/^$/d' $MAIL | wc -c` echo `expr $B / $N` で、本文の平均バイト数が表示できます。

white-tiger
質問者

お礼

ありがとうございます。試してみてちょっと感動しました。 ひとつだけ質問があるのですが、 「/^From /,/^$/」はどういう意味でしょうか? ものの本を見ると、SED のコンマは範囲指定で、上の例だと 「先頭がFromの行、から、先頭が行末(空行)の行まで」 となるのでしょうか? このばあい、本文中に空行があると、そこをメールの終わりの行と勘違いしてしまわないでしょうか? もし、とんちんかんなことを書いていたらすみません。 よろしくお願いいたします。

  • mitoneko
  • ベストアンサー率58% (469/798)
回答No.2

 bashは、よくわかりませんが、  もし、ポートを開いて、テキストでコマンドを送る方法があるなら、ということで・・・(たとえば、telnetみたいな) ・メールサーバーのpop3ポートに接続します。 ・「+OK ・・・」が帰ってきます。 ・「USER ユーザー名」を送ります。 ・「+OK ・・・」が帰ってきます。 ・「PASS パスワード」を送ります。 ・「+OK ・・・」が帰ってきます。 ・「LIST」を送ります。 ・「+OK メールの総件数 メールの総バイト数」  の後に、  「通し番号 メールのバイト数」のリストが帰ってきます。  リストの最後には、行頭に「.」と入った行が送られます。 ・「QUIT」を送ります。 ・「+OK ・・・」が帰ります。  たとえば、TELNETで実験すると、つぎのような感じです。(送信も受信もべたで張ってますので、上の手順と比較してください。) ================================================== +OK <1085202620.3256@****.jp> ************* user ****** +OK Password required for ********* pass ******** +OK Maildrop has 223 messages (2307906 bytes) list +OK 223 2307906 1 1383 2 12555 ・・・・省略・・・・ 222 4872 223 3279 . quit +OK [**********] closing session ホストとの接続が切断されました。 ===================================================  当方のサーバーの個別データ等に関しては「****」で置き換えさせて頂いています。  このLISTコマンドの結果を加工すれば、メールヘッダー込みのバスト数で集計できます。  サーバーによって、レスポンスは微妙に違いますが、コマンドは、RFCで定義されているものなので、基本的には、どんなサーバーでもPOP3アクセスをサポートしていれば、結果は取れると思います。  LISTコマンドの発行だけであれば、ごく短時間で取り込めるはずです。  本分バイト数となると、ヘッダを全メール分取り込むしか方法がないと思います。#1さんの手法になるでしょう。まして、文字数となると、もう全部受信して本分を解析するより手がありません。

white-tiger
質問者

お礼

できました。すばらしい。 こんなことができるんですね。

  • notnot
  • ベストアンサー率47% (4900/10358)
回答No.1

Solarisの場合は、Content-Length: というヘッダに本文長が入るはずなので、 awk '/^Content-Length:/{L+=$2;++N}END{print L/N}' $MAIL で多分平均が出ると思います。たまたま本文中にContent-Length: があれば狂いますが多分大丈夫でしょう。 もし、Content-Length: ヘッダが無いようなら補足ください。

white-tiger
質問者

お礼

ありがとうございます。 すみません、Content-Length: ヘッダはないようです。

関連するQ&A