我如何以智能的方式比较两个 mbox 文件?

我如何以智能的方式比较两个 mbox 文件?

我有两个 mbox 文件,每个文件包含大约 6000 封电子邮件。它们应该大致相同,但 #1 包含大约 100 封电子邮件,而 #2 不包含。我很想生成第三个 mbox 文件,其中包含我的 100 封邮件 - 可以说是一个差异。

我曾经自动将消息从一个收件箱转发到另一个收件箱(服务器端),但由于某些奇怪的不确定的原因,它会随机地不转发几封消息。#2 是电子邮件被转发到的收件箱 - 大量已读和已回复的消息,带有附加标题,其中包含有关如何转发它们的信息。#1 是最近使用 imap 转储的 6k 条未读消息。


我在 Linux 下使用 Thunderbird。

答案1

以下 Python 脚本解决了该问题:

import mailbox

inbox_2 = mailbox.mbox('inbox_2_file')
inbox_1 = mailbox.mbox('inbox_1_file')

inbox_diff = mailbox.mbox('inbox_diff_file', create=True)

inbox_2_ids = []
for message in inbox_2:
    inbox_2_ids.append(message.get('Message-ID'))

for message in inbox_1:
    if message.get('Message-ID') not in inbox_2_ids:
        inbox_diff.add(message)

inbox_diff.flush()

答案2

非常感谢@sme发布您的问题和答案。只要每封电子邮件都包含一个消息ID,Python脚本就可以完美运行。遗憾的是,情况并非总是如此,因为令人惊讶的是,Message-ID 不是必填字段

只需稍加改动,您的脚本便可用于创建一个新的 mbox 文件,其中包含所有缺少 Message-ID 字段的电子邮件消息:

import mailbox

inbox_1 = mailbox.mbox('inbox_1_file')

inbox_missing_message_id = mailbox.mbox('inbox_missing_message_id_file', create=True)

for message in inbox_1:
    if message.get('Message-ID') is None:
        inbox_missing_message_id.add(message)

inbox_missing_message_id.flush()

答案3

大约 5 年后。我必须比较 306MB 和 338MB 的 Thunderbird 备份邮箱。因此,我将所有出色的建议都放入一个独立的帮助脚本中,该脚本可以区分 mbox2 - mbox1。在此过程中,还会创建相应的邮箱,其中包含缺少 Message-ID 字段的电子邮件。对我来说,这在 Mac 上开箱即用,生成两个额外的邮箱,其中的电子邮件没有 52KB 和 10KB 的 Message-ID。非常容易管理!

希望这能派上用场。感谢您的见解。

#!/usr/bin/env python3

import mailbox
import sys
import os

if len(sys.argv) <= 2:
    print("USAGE: {} <mbox2> <mbox1>".format(os.path.basename(sys.argv[0])))
    print("       <diff> = <mbox2> - <mbox1> is based on 'Message-ID' field")
    print("       E-mails with no 'Message-ID' are copied <mbox[1|2]_no_Message-ID>.")
    print("       Original mailboxes are left unaltered.")
    sys.exit(1)
    
if not os.path.isfile(sys.argv[1]):
    print(" * mbox_file {} does not exist.".format(sys.argv[1]))
    sys.exit(2)
if not os.path.isfile(sys.argv[2]):
    print(" * mbox_file {} does not exist.".format(sys.argv[2]))
    sys.exit(2)

mbox1_file = sys.argv[1]
mbox2_file = sys.argv[2]

outfile = os.path.join(
    os.path.dirname(mbox1_file)
    , '{}2_diff_{}1'.format(os.path.basename(mbox2_file), os.path.basename(mbox1_file))
)
if os.path.isfile(outfile):
    print(" * OUTPUT mbox_file {} already exists.".format(outfile))
    sys.exit(2)

nomsgid1_file = os.path.join(
    os.path.dirname(mbox1_file)
    , '{}_no_Message-ID'.format(os.path.basename(mbox1_file))
)
if os.path.isfile(nomsgid1_file):
    print(" * OUTPUT mbox_file {} already exists.".format(nomsgid1_file))
    sys.exit(2)


nomsgid2_file = os.path.join(
    os.path.dirname(mbox2_file)
    , '{}_no_Message-ID'.format(os.path.basename(mbox2_file))
)
if os.path.isfile(nomsgid2_file):
    print(" * OUTPUT mbox_file {} already exists.".format(nomsgid2_file))
    sys.exit(2)


inbox_1 = mailbox.mbox(mbox1_file)
inbox_2 = mailbox.mbox(mbox2_file)
inbox_diff = mailbox.mbox(outfile, create=True)
inbox1_missing_message_id = mailbox.mbox(nomsgid1_file, create=True)
inbox2_missing_message_id = mailbox.mbox(nomsgid2_file, create=True)


inbox_2_ids = []
for message in inbox_2:
    msgid = message.get('Message-ID')
    if msgid is None:
        inbox2_missing_message_id.add(message)
    else:
        inbox_2_ids.append(msgid)

for message in inbox_1:
    msgid = message.get('Message-ID')
    if msgid is None:
        inbox1_missing_message_id.add(message)
    elif msgid not in inbox_2_ids:
        inbox_diff.add(message)

inbox_diff.flush()
inbox2_missing_message_id.flush()
inbox1_missing_message_id.flush()

PS 我还遇到了几个编码问题。如您所知,很难自动检查电子邮件的编码是否正确,而 utf-8 并不总是有效。一个残酷但有效的解决方案是将库ascii中出现的每个编码更改mailbox.py为 和latin-1utf8如下所示:

get_message功能:

try:
  msg.set_from(from_line[5:].decode('latin-1'))
except Exception as e:
  msg.set_from(from_line[5:].decode('utf8'))
return msg

_install_message()功能:

author = message.get_from().encode('utf8')
[...]
from_line = from_line.encode('utf8')

相关内容