procmail 在文件名中保存带有接收日期的附件

procmail 在文件名中保存带有接收日期的附件

我们每天都会收到一封电子邮件,例如[电子邮件受保护]带附件,文件名是例如report.xlsx

如何保存带有收到日期的文件?例如20180131_report.xlsx,我如何过滤主题或发件人?

我的〜/ .procmailrc:

:0
*^content-Type:
{
    :fw
    | ripmime --overwrite --no-nameless -i - -d /dir/to/save/attachment
}

答案1

如果你的 Procmail 或接收 MTA 配置为From_线在消息本身之前,这个伪标头通常已经包含日期。您需要解析它,这很麻烦,所以除非这是一个您确实需要优化性能的系统(在这种情况下每秒数百个匹配?),绝对最简单的解决方案是调用date +%Y%m%d.

要匹配两个不相关标头中的任何一个,只需将它们都放入正则表达式中|

:0
* ^Content-type:
* ^From:(.*\<)?foo@example\.tld|^Subject: Your daily report
| ripmime --overwrite --no-nameless -i - -d /dir/to/save/attachment/$(date +%Y%m%d)_report.xslx

(此处存在错误;请参阅下面的更新。)

这些fw标志在这种情况下没有意义,所以我把它们去掉了(实际上我也不确定这个Content-type:条件是否有意义;无论如何,现在大多数消息都会有它)。

如果您想要组合更复杂的条件,您可以使用称为德摩根定律的逻辑基本原理。没有直接的Procmail 中的语法表示“这个条件或那个条件”,但是你可以重构这个到“不是((不是这个条件)和(不是那个条件))”。

:0
* ! this condition
* ! that condition
{ } # nothing happens here
:0E # else
{ LOG="at least one of them matched
" }

或者干脆使用评分;

:0
* 1^0 this condition
* 1^0 that conditon
{ LOG="at least one of them matched
" }

更新:

看起来像ripmime实际上并不支持(提取或)命名单个附件。最简单的解决方案可能是cron在午夜之前重命名最晚到达的时间(或者如果您知道它何时到达,则比您期望的最晚时间晚一点):

 55 23 * * * cd /dir/to/save/attachment && mv report.xslx "$(date +%%Y%%m%%d)"_report.xslx

请注意,您如何(特别地)需要将命令中的任何百分号加倍cron!显然,您可以将上面的 Procmail 配方恢复为简单地保存ripmime/dir/to/save/attachment

或者,我会在附件到达后立即对其进行重命名,也许同时也会大大收紧条件。以下内容包含大量关于如何进行的猜测确切地传递附件的消息是经过编码的——它可以在多种不同的内容类型、MIME 结构、MIME 标头约定等之间进行选择,因此如果不进行一些调整,它可能无法工作。

:0
* ^From:(.*\<)?foo@example\.tld
* ^Subject: Your daily report
* HB ?? ^Content-type: application/(octet-stream|vnd\.openxmlformats-officedocument\.spreadsheetml\.sheet|vnd\.ms-here-be-dragons-xslx); filename="?report.xslx
| ( cd dir/to/save/attachment; \
    ripmime --overwrite --no-nameless -i - -d . && \
    mv report.xslx $(date +%Y%m%d)"_report.xslx )

Content-type:头可能不包含文件名;它可以(而且现在应该)被指定,Content-Disposition:但许多发件人将其放在两个地方以实现向后兼容性。文件名应该正确地进行 RFC2231 编码,这意味着可以填充许多可选字段,我方便地假设它们将为空,就像 ASCII 文件名是镇上唯一的游戏时一样。

另请注意我如何要求发件人现在要匹配的主题。它HB ??说(不准确地)在主消息标头或正文中的某个位置查找匹配项。正确地说,在后一种情况下,匹配应该位于 MIME 正文部分的标头中,但 Procmail 没有简单的方法来指定这一点。

答案2

回答您的每个问题:

  1. 您可以从配方中调用外部命令,因此您可以执行以下操作来定义变量TODAY

    TODAY=`date +%Y%m%d`
    

    然后你可以在你的食谱中引用它:

    ripmime --overwrite --no-nameless -i - -d /dir/to/save/attachment/$TODAY_report_xlsx
    

    如果您需要动态确定文件名,请相应地调整配方。

  2. 过滤某个主题作为发件人,您可以执行以下操作:

    :0
    * ^content-Type:
    * ^From:.* [email protected]
    * ^Subject:.*Report
    {
    ....
    

相关内容