-1

我有一个隔离文件夹,我必须定期下载并按收件人收件箱拆分,或者更好地将每封邮件拆分为文本文件。我每天有大约 10.000 封邮件,我正在用 fetchmail 和 procmail 编写一些东西。问题是我不知道如何在 procmail 中逐条拆分消息;他们最终都在同一个收件箱中。

我试图通过如下配方传递脚本中的每条消息:

    :0
    | script_processing_messages.sh

其中包含

    read varname
    echo "$varname" > test_file

为了尝试查看是否可以在 $varname 变量中获得一条消息但不行,我每次只获得一行消息。

现在我用

    fetchmail --keep

.fetchmailrc 在哪里

    poll mail.mymta.my protocol pop3 username "my@inbox.com" password "****" mda "procmail /root/.procmailrc"

和 .procmailrc 是

    VERBOSE=0
    DEFAULT=/root/inbox.quarantine

我想为每条消息获取一个文件,所以:

1.txt
2.txt
3.txt
[...]
10000.txt

我有很多收件人和很多域,所以我不能说编写 5000 条规则来匹配每个收件人。如果有某种形式就好了

^To: $USER 

重定向到

/$USER.inbox

以便 procmail 本身负责阅读和动态创建这些收件箱

我不是 fetchmail 和 procmail 食谱方面的专家,我正在努力,但我不会走得太远。

4

2 回答 2

1

你似乎有两三个不同的问题;Stack Overflow 上的正确礼仪是分别询问每个人 - 这也有助于未来的访问者遇到您的问题之一。

首先,要拆分包含多条消息的 Berkeley mbox 文件并分别在每个消息上运行 Procmail,请尝试

formail -s procmail -m <file.mbox

您可能需要阅读Procmail 支持的邮箱格式。伯克利邮箱是一个包含多条消息的单个文件,只需用一行开头From(四个字母字符后有一个空格)分隔。这个分隔符必须是唯一的,因此在正文中包含这五个字符的消息将需要以某种方式进行转义(通常通过编写>before From)。

要将每封邮件保存在单独的文件中,请选择与单文件伯克利格式不同的邮箱格式。具体来说,如果目标是一个目录,Procmail 将在该目录中创建一个新文件。新文件的确切命名方式取决于目录的内容(如果它包含 Maildir 子目录newtmpcur,则新文件是new根据 Maildir 命名约定创建的)以及目录的具体指定方式(斜杠和dot 选择 MH 格式;否则为邮件目录格式)。

保存到每个收件人一个邮箱有许多讨厌的角落案例。如果邮件发送给多个本地收件人怎么办?如果收件人地址在标头中不可见怎么办?等等(Procmail Mini-FAQ 有一个关于这个的部分,在域的虚拟主机的上下文中,这基本上是一个变体)。但如果我们简单地忽略这些,你也许可以用类似的东西来完成它

:0  # whitespace before ] is a literal tab
* ^TO_\/[^ @    ]+@(yourdomain\.example|example\.info)\>
{
    # Trim domain part from captured MATCH
    :0
    * MATCH ?? ^\/[^@]+
    ./$MATCH/
}

这将捕获与正则表达式匹配的第一个地址,然后对捕获的字符串执行另一个正则表达式匹配以仅捕获符号$MATCH之前的部分。@这显然要求您要匹配的地址都在一组特定域中(在这里,我使用yourdomain.exampleand example.info; 显然用您的实际域名替换那些)并且捕获第一个匹配地址就足够了(所以如果一条消息是To: alice@yourdomain.example并且Cc: bob@example.info,其中一个更接近消息顶部的将被此配方挑选出来,而另一个将被忽略)。

更详细地说,\/特殊标记使 Procmail 将在此点之后与正则表达式匹配的文本复制到内部变量MATCH中。正如这个秘籍所展示的,你可以在那个变量本身上执行一个正则表达式匹配来提取它的一个子字符串(或者,换句话说,丢弃部分捕获的匹配)。

该操作./$MATCH/使用捕获的字符串 inMATCH作为要保存到的文件夹的名称。前导./指定当前目录(等于 Procmail 变量的值MAILDIR),尾随/选择邮件目录格式。

如果您的预期收件人不能被限制在一组特定的域中或以其他方式与单个正则表达式匹配,我的建议是提出一个范围更有限的新问题,并提供足够的详细信息来实际确定您想要完成的任务。

于 2019-07-08T10:09:38.023 回答
0

我找到了解决部分问题的方法。

似乎procmail没有办法让procmail本身识别For收件人而不在recipe中指定它,所以我只是获取了一个列表并创建了一个巨大的recipe文件。

但后来我发现,为了节省单个邮件并避免装满大量邮件的巨大邮箱,可以编写如下配方:

:0
* ^To: recipient@mail.it
/inbox/folder/recipient@mail.it/

注意/最后:这将使 procmail 创建一个文件夹结构,而不是将所有内容都写入一个文件中。

于 2019-07-05T08:13:51.683 回答