またもや管理しているメールサーバでUnable to process From lines (envelopes), change recognition modes or check for corrupted mail drop.Commentsが起こったので、mbox形式のファイルを1メール1ファイルに分割するスクリプトを作った。ruby 2.1.0 で動作することを確認した。
以下を mbox2eml.rb として保存したとする。
# -*- coding: utf-8 -*-
require 'rubygems'
require 'mail' # https://github.com/mikel/mail/blob/master/README.md
require 'time'
class Mbox
attr_reader :dirname
def initialize(mboxFilename)
if File.exist?(mboxFilename)
@mboxFilename = mboxFilename
@dirname = "#{@mboxFilename}_dir"
@counter = 0
else
print "error: #{@mboxFilename} isn't in this directory!\n"
exit
end
end
def mkdirForEML
Dir.mkdir(@dirname, 0755)
end
def divideToEML
messageBuff = String.new
File.open(@mboxFilename, "r") do | input |
while line = input.gets
line.scrub!('?')
if (line.match(/\AFrom /))
unless messageBuff.empty?
@counter += 1
File.open("#{@dirname}/#{@counter}", "w") do | output |
output.puts messageBuff
end
messageBuff = ''
end
else
messageBuff << line.sub(/^\>From/, 'From')
end
end
end
end
end
class EMLList
def initialize(dirname)
if File.exist?(dirname)
@fileLists = Dir.glob("#{dirname}/[0-9]*")
@fileLists.sort!{|a, b| File.basename(a).to_i <=> File.basename(b).to_i}
else
print "error: #{dirname} isn't in this directory!\n"
exit
end
end
def showInfo
@fileLists.each{|filename|
unless filename.nil?
mail = Mail.read(filename)
puts "== #{filename} =="
puts "From: #{mail.from.to_s}"
subject = mail.subject.to_s
if subject.empty?
puts "Subject: == empty =="
else
puts "Subject: #{mail.subject.to_s}"
end
time = mail.date.to_s
unless time.empty?
puts "Time: #{Time.parse(time)}"
else
puts "Time: == can't get timestamp == "
end
puts "\n"
end
}
end
end
begin
if ARGV.length != 1
puts "error: please input mbox filename.\n"
exit
end
mboxFilename = ARGV[0]
mbox = Mbox.new(mboxFilename)
mbox.mkdirForEML
mbox.divideToEML
emls = EMLList.new(mbox.dirname)
emls.showInfo
rescue => ex
puts ex.message
endこのスクリプトは rubygemsのmail ライブラリを使用している。なので、事前にインストールしておくこと。
% gem install mail
mbox形式のファイルを mbox.bak として保存していたとき、以下のようにして利用する。
% ruby mbox2eml.rb mbox.bak |& tee list.txt
mbox.bak_dir というディレクトリが作成され、その中に数字がファイル名のファイルが生成される。list.txt には、以下の情報がメールごとに表示される。「XX」は mbox.bak_dir 以下にあるファイル名(数字)。
- == mbox.bak_dir/XX ==
- From: 差出人メールアドレス
- Subject: 件名
- Time: 受信時刻