我有一些 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))
使用
- 将脚本复制到一个空文件中,另存为
group_domains.py
使用目标目录作为参数运行它:
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]
笔记
事实上,脚本会创建一个输出每个文件在终端中。我们可以轻松地合并(总结)单独文件的输出,然后将分组结果写入文件等,但请提及。
解释
在概念上:
- 读取文件的行,并用“@”分隔以读取域
创建的列表随后已排序按域名:
lines.sort(key=itemgetter(1))
并按域分组:
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")
使用
- 将脚本复制到一个空文件中
运行:
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