我是bash的新手,对理解如何完成此操作有疑问。
选中所有“收件人:”字段电子邮件地址域,并将所有唯一域列出到变量中,以便与域进行比较。
我通过
获得“发件人地址”域grep -m 1 "From: " filename | cut -f 2 -d '@' | cut -d ">" -f 1
读取存储在文件名中的邮件时。
对于“寻址”域,可以有多个“收件人:”地址,并且具有多个域。我不确定如何从“到地址字段”获取唯一域。
地址行示例如下:
To: user@domain.com, user2@domain.com,
User Name <sample@domaintest.com>, test@domainname.com
grep -m 1 "^To: " filename | cut -f 2 -d '@' | cut -d ">" -f 1
,但是电子邮件格式不同。因此,我不确定grep
是否正确,还是应该搜索awk或其他内容。
我需要从“收件人:”字段的电子邮件地址中获取唯一域列表,然后将其发送到bash脚本中的变量。
上述示例的所需输出:
domain.com,domaintest.com,domainname.com
答案 0 :(得分:0)
电子邮件地址标准化很棘手,因为有很多变体可供选择。
From: Elvis Parsley <king@graceland.example.com>
From: king@graceland.example.com
From: "Parsley, Elvis" <king@graceland.example.com> (kill me, I have to use Outlook)
From: "quoted@string" <king@graceland.example.com> (wait, he is already dead)
To: This could fold <recipient@example.net>,
over multiple lines <another@example.org>
我将转向一种功能更强大的语言,并为解析所有这些格式提供适当的支持。我的选择是Python,尽管您也可以在几行Ruby或Perl中实现这一点。
email
库在Python 3.6中进行了改进,因此假定您至少拥有该版本。在{3.6}中新增的email.Headerregistry
类在这里特别方便。
#!/usr/bin/env python3
from email.policy import default
from email import message_from_binary_file
import sys
if len(sys.argv) == 1:
sys.argv.append('-')
for arg in sys.argv[1:]:
if arg == '-':
handle = sys.stdin
else:
handle = open(arg, 'rb')
message = message_from_binary_file(handle, policy=default)
from_dom = message.get('From').address.domain
to_doms = set()
for addr in message.get('To').addresses:
dom = addr.domain
if dom == from_dom:
continue
to_doms.add(dom)
print(','.join([from_dom] + list(to_doms)))
if arg != '-':
handle.close()
这只会产生一个逗号分隔的域名列表;您可能还想在Python中进行其余的处理,或者更改此方法以使其以稍微不同的格式打印内容。
您将其保存在方便的位置(例如/usr/local/bin/fromto
)并将其标记为可执行文件(chmod 755 /usr/local/bin/fromto
)。现在,您可以像其他grep
之类的其他实用程序一样从外壳程序调用它。
答案 1 :(得分:0)
如果您想通过面向行的实用程序来做到这一点,那么Procmail发行版中有一个实用程序formail
,可以为您一些规范化的事情。
bash$ formail -czxTo: <<\==test==
> From: me <sender@example.com>
> To: you <first@example.org>,
> them <other@example.net>
> Subject: quick demo
>
> Very quick, innit.
> ==test==
first@example.org, other@example.net
因此,您有了输入,您实际上可以将其传递给grep
或Awk ...或sed
。
fromdom=$(formail -czxTo: <message | tr ',' '\n' | sed 's/.*@//')
From:
不会对formail -czxFrom:
地址进行规范化,但是您可以使用巧妙的技巧:使formail
生成对From:
地址的回复,然后提取To:
标头。
todoms=$(formail -rtzcxTo: <message | sed 's/.*@//')
更详细地讲,-r
表示要对发送给您message
的任何人进行新的回复,然后我们对{em>那做-zcxTo:
。 >
(-t
选项可能会或可能不会执行您想要的操作。在这种情况下,我可能会忽略它。http://www.iki.fi/era/procmail/formail.html的操作说明不明确;另请参见本节。 http://www.iki.fi/era/procmail/mini-faq.html#group-writable之前,并且对于笨拙的链接感到抱歉-似乎没有很好的链接到页面内部的锚点。)