我如何按域名对电子邮件进行分组,并将其与目录中的所有文件进行合并和汇总?

我如何按域名对电子邮件进行分组,并将其与目录中的所有文件进行合并和汇总?

我有一些 CSV 文件。每个文件都有一个电子邮件地址列表。以下是从文件中提取的数据:

%%%%%%%%%%@yahoo.com
%%%%%%@wanadoo.fr
%%%%[email protected]
%%nameemail%%@yahoo.com
%[email protected]
%1%[email protected]
%[email protected]

我想要尝试的是从这些电子邮件地址中提取域名,然后以某种方式排列电子邮件地址,以便将与特定域名相关的电子邮件列在一起。
例如:

yahoo.com,%%%%%%%%%%@yahoo.com
wanadoo.fr,%%%%%%@wanadoo.fr
yahoo.comravi,%%%%[email protected]
yahoo.com,%%nameemail%%@yahoo.com
numberland.com,%[email protected]
example.com,%1%[email protected]
example.com,%[email protected]

我尝试获取的最终输出如下:

yahoo.com,%%%%%%%%%%@yahoo.com,%%nameemail%%@yahoo.com
wanadoo.fr,%%%%%%@wanadoo.fr
yahoo.comravi,%%%%[email protected]
numberland.com,%[email protected]
example.com,%1%[email protected],%[email protected]

答案1

一种 Python 方式,使用itertools' groupby()

1. 在终端中按文件(目录中的所有文件)写入输出

注意,终端显示的行数有限

#!/usr/bin/env python3
from operator import itemgetter
from itertools import groupby
import os
import sys

dr = sys.argv[1]

for f in os.listdir(dr):
    lines = [[l.strip(), l.split("@")[-1].strip()] for l in \
             open(os.path.join(dr, f)).readlines()]
    lines.sort(key=itemgetter(1))
    for item, occurrence in groupby(lines, itemgetter(1)):
        func = [s[0] for s in list(occurrence)]; print(item+","+",".join(func))

使用

  1. 将脚本复制到一个空文件中,另存为group_domains.py
  2. 使用目标目录作为参数运行它:

    python3 /path/to/group_domains.py /directory/with/files
    

输出将会像这样:

example.com,%1%[email protected],%[email protected]
numberland.com,%[email protected]
wanadoo.fr,%%%%%%@wanadoo.fr
yahoo.com,%%%%%%%%%%@yahoo.com,%%nameemail%%@yahoo.com
yahoo.comravi,%%%%[email protected]

笔记

事实上,脚本会创建一个输出每个文件在终端中。我们可以轻松地合并(总结)单独文件的输出,然后将分组结果写入文件等,但请提及。

解释

在概念上:

  1. 读取文件的行,并用“@”分隔以读取域
  2. 创建的列表随后已排序按域名:

    lines.sort(key=itemgetter(1))
    
  3. 并按域分组:

    groupby(lines, itemgetter(1))
    

结果(线)由项目(域)及其“成员”组成。

2. 将每个文件的报告(再次针对目录中的所有文件)写入重命名的文件中。

下面的脚本将把输出写入重命名的文件中,用法相同:

#!/usr/bin/env python3
from operator import itemgetter
from itertools import groupby
import os
import sys

dr = sys.argv[1]


for f in os.listdir(dr):
    write = []
    file = os.path.join(dr, f)
    lines = [[l.strip(), l.split("@")[-1].strip()] for l in open(file).readlines()]
    lines.sort(key=itemgetter(1))
    for item, occurrence in groupby(lines, itemgetter(1)):
        func = [s[0] for s in list(occurrence)]
        write.append(item+","+",".join(func))
    open(os.path.join(dr, "grouped_"+f), "wt").write("\n".join(write))

来自如下文件:

some_list.txt

它将创建一个重命名的:

grouped_some_list.txt

使用

简单地:

python3 /path/to/group_domains.py /directory/with/files

3. 将整个目录的报告(摘要)写入单个文件

以下版本将汇总目录中文件内的所有域。报告保存在文件中,以设置为第二个参数。

#!/usr/bin/env python3
from operator import itemgetter
from itertools import groupby, chain
import os
import sys

dr = sys.argv[1]
outfile = sys.argv[2]

report = []

for f in os.listdir(dr):
    lines = [[l.strip(), l.split("@")[-1].strip()] for l in \
             open(os.path.join(dr, f)).readlines()]
    lines.sort(key=itemgetter(1))
    for item, occurrence in groupby(lines, itemgetter(1)):
        func = [s[0] for s in list(occurrence)]
        report.append([item, func])

report.sort(key=itemgetter(0))

with open(outfile, "wt") as out:
    for item, occurrence in groupby(report, itemgetter(0)):
        func = [item for sublist in [it[1] for it in list(occurrence)] for item in sublist]
        out.write(item+","+",".join(func)+"\n")

使用

  1. 将脚本复制到一个空文件中
  2. 运行:

    python3 /path/to/group_domains.py /directory/with/files /path/to/outputfile.txt
    

    (或任何扩展名)

笔记

最后一个版本将首先总结每个文件,正如问题中提到的,此外将所有文件汇总到一个输出文件中,其中来自单独文件的类似域将合并为每个域一行。

答案2

这是一个perl使用匿名数组哈希的版本:

$ perl -F@ -alne '
    push @{ $h{$F[1]} }, $_ }{ 
    for $k (reverse sort keys %h) {print join ",", $k, @{ $h{$k} }
  }' emails.csv
yahoo.comravi,%%%%[email protected]
yahoo.com,%%%%%%%%%%@yahoo.com,%%nameemail%%@yahoo.com
wanadoo.fr,%%%%%%@wanadoo.fr
numberland.com,%[email protected]
example.com,%1%[email protected],%[email protected]

该订单不是确切地你要求什么

答案3

使用awk

awk -F, '{a[$1] = a[$1]","$2} END {for (i in a) print i a[i]}'

输出没有任何特定顺序:

$ awk -F, '{a[$1] = a[$1]","$2} END {for (i in a) print i a[i]}' foo
yahoo.comravi,%%%%[email protected]
yahoo.com,%%%%%%%%%%@yahoo.com,%%nameemail%%@yahoo.com
numberland.com,%[email protected]
example.com,%1%[email protected],%[email protected]
wanadoo.fr,%%%%%%@wanadoo.fr

相关内容