FaxMax Asked: 2018-02-03 05:24:22 +0800 CST2018-02-03 05:24:22 +0800 CST 2018-02-03 05:24:22 +0800 CST procmail 在文件名中保存带有接收日期的附件 772 每天我们都会收到一封来自例如 foo@example.tld 的带有附件的电子邮件,文件名是例如report.xlsx 如何使用接收日期保存文件?例如20180131_report.xlsx,我如何过滤主题或发件人? 我的~/.procmailrc: :0 *^content-Type: { :fw | ripmime --overwrite --no-nameless -i - -d /dir/to/save/attachment } email procmail 2 个回答 Voted Best Answer tripleee 2018-02-03T06:38:40+08:002018-02-03T06:38:40+08:00 如果您的 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 没有简单的方法来指定这一点。 mjturner 2018-02-03T06:16:01+08:002018-02-03T06:16:01+08:00 回答您的每个问题: 您可以从配方中调用外部命令,因此您可以执行以下操作来定义变量TODAY: TODAY=`date +%Y%m%d` 然后,您可以在食谱中引用它: ripmime --overwrite --no-nameless -i - -d /dir/to/save/attachment/$TODAY_report_xlsx 如果您需要动态确定文件名,请相应地调整配方。 要过滤主题和发件人,您可以执行以下操作: :0 * ^content-Type: * ^From:.* foo@example.tld * ^Subject:.*Report { ....
如果您的 Procmail 或接收 MTA 被配置为在消息之前放置
From_
一行,则此伪标头通常已经包含日期。你需要解析它,这是一个拖累,所以除非这是一个你真的需要优化性能的系统(在这种情况下每秒数百次匹配?)绝对最简单的解决方案是调用date +%Y%m%d
.要匹配两个不相关的标题中的任何一个,只需将它们都放在一个正则表达式中
|
:(此处有错误;请参阅下面的更新。)
这些
fw
标志在这种情况下没有意义,所以我把它们拿出来(实际上我也不确定这个Content-type:
条件是否有意义;这些天大多数消息都会有它)。如果您想要组合更复杂的条件,您可以使用逻辑中的一个基本原理,称为德摩根定律。Procmail中没有直接的语法来表示“这个条件或那个条件”,但您可以将它重构为“不是((不是这个条件)和(不是那个条件))。
或者干脆使用打分;
更新:
看起来
ripmime
实际上并不支持(提取或)命名单个附件。最简单的解决方案可能是cron
在午夜之前重命名最新到达的工作(或者如果您知道它何时到达,则在您期望的最晚时间之后一点):请注意(特别)您需要将命令中的任何百分号加倍
cron
!您显然会将上面的 Procmail 配方恢复为只需ripmime
保存到/dir/to/save/attachment
或者,我会在附件到达后立即重命名,也许同时也会大大收紧条件。以下包括大量关于传递附件的消息是如何编码的猜测——它可以在许多不同的内容类型、MIME 结构、MIME 标头约定等之间进行选择,因此如果没有它可能无法工作一些调整。
标
Content-type:
头可能不包含文件名;它可以(并且现在应该)在其中指定,Content-Disposition:
但许多发件人将它放在两个地方以实现向后兼容性。文件名应该正确地采用 RFC2231 编码,这意味着可以填充许多可选字段,我方便地假设它们将为空,就像 ASCII 文件名是城里唯一的游戏一样。还要注意我现在如何要求发件人和主题匹配。说(不精确地)在
HB ??
主消息标题或正文中的某个位置查找匹配项。正确地说,在后一种情况下,匹配应该在 MIME 正文部分的标头中,但 Procmail 没有简单的方法来指定这一点。回答您的每个问题:
您可以从配方中调用外部命令,因此您可以执行以下操作来定义变量
TODAY
:然后,您可以在食谱中引用它:
如果您需要动态确定文件名,请相应地调整配方。
要过滤主题和发件人,您可以执行以下操作: