9

所以我已经通读了这个关于 SO 的问题,但它对我没有任何帮助。我想将 Gmail 生成的 mbox 文件导入另一个网络邮件服务,但问题是每次导入它只允许 40 MB 大文件。

所以我不得不以某种方式将 mbox 文件拆分为 max. 40 MB 大文件,一个接一个地导入。你会怎么做?

formail我最初的想法是使用另一个脚本(

我也查看了split命令,但我担心它会切断邮件。谢谢你的帮助!

4

4 回答 4

13

如果您mbox是标准格式,则每条消息都将以From空格开头:

From someone@somewhere.com

因此,您可以COPY YOUR MBOX TO A TEMPORARY DIRECTORY并尝试使用awk来逐个消息地处理它,仅在任何消息的开头拆分。假设我们每个输出文件有 1,000 条消息:

awk 'BEGIN{chunk=0} /^From /{msgs++;if(msgs==1000){msgs=0;chunk++}}{print > "chunk_" chunk ".txt"}' mbox

然后您将获得调用chunk_1.txtchunk_n.txt每个包含多达 1,000 条消息的输出文件。

如果您不幸在 Windows 上(无法理解单引号),您需要将以下内容保存在一个名为awk.txt

BEGIN{chunk=0} /^From /{msgs++;if(msgs==1000){msgs=0;chunk++}}{print > "chunk_" chunk ".txt"}

然后输入

awk -f awk.txt mbox
于 2015-01-23T14:07:41.917 回答
11

我刚刚从Mark Sechell 的回答中改进了一个脚本。正如我们所看到的,该脚本可以根据每个块的电子邮件数量来解析 mbox 文件。这个改进的脚本可以根据每个块的定义的最大大小来解析 mbox 文件。
因此,如果您在上传或导入 mbox 文件时有大小限制,您可以尝试使用下面的脚本将 mbox 文件拆分为具有指定大小*的块。
将下面的脚本保存到一个文本文件中,例如mboxsplit.txt,在包含 mbox 文件的目录中(例如命名mbox):

BEGIN{chunk=0;filesize=0;}
    /^From /{
    if(filesize>=40000000){#file size per chunk in byte
        close("chunk_" chunk ".txt");
        filesize=0;
        chunk++;
    }
  }
  {filesize+=length()}
  {print > ("chunk_" chunk ".txt")}

然后在该目录中运行/键入这一行(包含mboxsplit.txtmbox文件):

  awk -f mboxsplit.txt mbox

请注意

  • 结果的大小可能大于定义的大小。它取决于在检查块大小之前插入缓冲区/块的最后一个电子邮件大小。
  • 它不会拆分电子邮件正文
  • 如果电子邮件大小大于指定的块大小,则一个块可能只包含一封电子邮件

我建议您将块大小指定为小于或小于最大上传/导入大小。

于 2017-03-06T11:23:05.210 回答
1

formail非常适合这项任务。你可以看看formail的+skip-total选项

选项
...
+skip在拆分时
跳过第一条跳过消息。
-total拆分
时最多输出消息。

根据您的邮箱和邮件的大小,您可以尝试

formail -100 -s <google.mbox >import-01.mbox
formail +100 -100 -s <google.mbox >import-02.mbox
formail +200 -100 -s <google.mbox >import-03.mbox

等等

当然,这些部件不必具有相同的尺寸。如果有一封大电子邮件,您可能只有formail +100 -60 -s <google.mbox >import-02.mbox,或者如果有很多小邮件,则可能是formail +100 -500 -s <google.mbox >import-02.mbox

要查找每个块的初始邮件数,请尝试

formail -100 -s <google.mbox | wc
formail -500 -s <google.mbox | wc
formail -1000 -s <google.mbox | wc

您可能需要进行一些试验,以适应您的邮箱大小。另一方面,由于这似乎是一次性任务,您可能不想在此上花费太多时间。

于 2019-04-15T08:24:54.373 回答
0

我最初的想法是使用另一个脚本(formail)将每封邮件保存为一个文件,然后运行一个脚本将它们组合成 40 MB 的大文件,但我仍然不知道如何使用终端来执行此操作。

如果我理解正确,您想将文件拆分,然后在导入之前将它们组合成一个大文件。这听起来像是做什么splitcat打算做什么。Split 根据您的大小规格拆分文件,无论是基于行还是字节。然后它为这些文件添加后缀以保持它们的顺序,然后您可以使用cat将文件重新组合在一起:

$ split -b40m -a5 mbox  # this makes mbox.aaaaa, mbox.aaab, etc.

在其他系统上获取文件后:

$ cat mbox.* > mbox

如果您想破坏文件以使邮件不会在文件之间拆分,则不会这样做,因为您要一次将每个文件导入新的邮件系统。

于 2015-01-23T14:56:33.567 回答