У меня есть некоторые файлы CSV. Каждый файл имеет список адресов электронной почты. Следующее является извлеченными данными из файла:
%%%%%%%%%%@yahoo.com
%%%%%%@wanadoo.fr
%%%%raviplywoodglasscentre@yahoo.comravi
%%nameemail%%@yahoo.com
%.getincontact@numberland.com
%1%3@example.com
%1@example.com
То, чего я пытаюсь делать попытку, извлекает домены из них адрес электронной почты и затем располагает адреса электронной почты таким способом, что электронные письма, связанные с определенным доменом, перечислены вместе.
Например:
yahoo.com,%%%%%%%%%%@yahoo.com
wanadoo.fr,%%%%%%@wanadoo.fr
yahoo.comravi,%%%%raviplywoodglasscentre@yahoo.comravi
yahoo.com,%%nameemail%%@yahoo.com
numberland.com,%.getincontact@numberland.com
example.com,%1%3@example.com
example.com,%1@example.com
Окончательный результат, который я пытаюсь получить, похож на следующее:
yahoo.com,%%%%%%%%%%@yahoo.com,%%nameemail%%@yahoo.com
wanadoo.fr,%%%%%%@wanadoo.fr
yahoo.comravi,%%%%raviplywoodglasscentre@yahoo.comravi
numberland.com,%.getincontact@numberland.com
example.com,%1%3@example.com,%1@example.com
Python путь, с помощью itertools
' groupby()
:
N.B. следите за этим, терминал показывает ограниченное количество строк
#!/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%3@example.com,%1@example.com
numberland.com,%.getincontact@numberland.com
wanadoo.fr,%%%%%%@wanadoo.fr
yahoo.com,%%%%%%%%%%@yahoo.com,%%nameemail%%@yahoo.com
yahoo.comravi,%%%%raviplywoodglasscentre@yahoo.comravi
Как это, сценарий создает вывод на файл в терминале. Мы могли легко объединиться (суммируют) вывод (выводы) отдельных файлов и впоследствии пишут сгруппированный результат в файл и т.д., но упомяните.
В понятии:
Созданный список впоследствии отсортирован по домену:
lines.sort(key=itemgetter(1))
и сгруппированный доменом:
groupby(lines, itemgetter(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):
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
Версия ниже будет суммировать все домены в файлах в каталоге. Отчет сохраняется в файле, для установки как второй аргумент.
#!/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
(или безотносительно расширения)
Последняя версия будет сначала подводить итог на файл, как упомянуто в вопросе, и дополнительно суммировать все файлы в выходной файл, где подобные домены из отдельных файлов будут объединены в одну строку на домен.
Используя 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,%%%%raviplywoodglasscentre@yahoo.comravi
yahoo.com,%%%%%%%%%%@yahoo.com,%%nameemail%%@yahoo.com
numberland.com,%.getincontact@numberland.com
example.com,%1%3@example.com,%1@example.com
wanadoo.fr,%%%%%%@wanadoo.fr
Вот a perl
версия, с помощью хеша анонимных массивов:
$ perl -F@ -alne '
push @{ $h{$F[1]} }, $_ }{
for $k (reverse sort keys %h) {print join ",", $k, @{ $h{$k} }
}' emails.csv
yahoo.comravi,%%%%raviplywoodglasscentre@yahoo.comravi
yahoo.com,%%%%%%%%%%@yahoo.com,%%nameemail%%@yahoo.com
wanadoo.fr,%%%%%%@wanadoo.fr
numberland.com,%.getincontact@numberland.com
example.com,%1%3@example.com,%1@example.com
Порядок не точно, что Вы попросили