pythonスクリプトを使用して、それぞれのメールからドメインを分離し、それぞれのドメインごとにメールをグループ化します。次のスクリプトは私のために機能します:
#!/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))
私は使用しました:python3 script.py /path/to/input files
入力した内容はメールのリストであり、次のように公開されました。
domain1.com,[email protected],[email protected]
domain2.com,[email protected],[email protected],[email protected]
しかし、問題が直面しているのは、MongoDBの制限によるものです。 MongoDBのドキュメントサイズは16 MBに制限されているため、出力ファイルの1行はMongoDBによって1つのドキュメントと見なされ、行サイズは16 MBを超えてはなりません。
したがって、結果はドメインごとに21通のメールに制限され、ドメインにさらにメールがある場合は、残りのメールと一緒に新しい行に印刷する必要があります(メールが21を超えている場合は、同じドメイン名の改行)。 mongoDBに重複データを保存します。
したがって、最終的な出力は次のようになります。
domain1.com,[email protected],[email protected],... [email protected]
domain1.com,[email protected],.....
domain2.com,[email protected],....
上記の例のドット(。)は多くのテキストを表していますが、理解しやすいように切り取りました。
これで私の問題が明確になり、解決策が得られることを期待してください。
あなたが投稿したスクリプトは、実際、メールをドメイン別にグループ化し、数に制限はありません。ドメインの下で電子メールをグループ化するが、見つかったリストを任意のチャンクに分割するバージョンの下。各チャンクは、対応するドメインで始まる行に印刷されます。
#!/usr/bin/env python3
from operator import itemgetter
from itertools import groupby, islice
import os
import sys
dr = sys.argv[1]
size = 3
def chunk(it, size):
it = iter(it); return iter(lambda: Tuple(islice(it, size)), ())
for f in os.listdir(dr):
# list the files
with open(os.path.join(dr, "chunked_"+f), "wt") as report:
file = os.path.join(dr, f)
# create a list of email addresses and domains, sort by domain
lines = [[l.strip(), l.split("@")[-1].strip()] for l in open(file).readlines()]
lines.sort(key=itemgetter(1))
# group by domain, split into chunks
for domain, occurrence in groupby(lines, itemgetter(1)):
adr = list(chunk([s[0] for s in occurrence], size))
# write lines to output file
for a in adr:
report.write(domain+","+",".join(a)+"\n")
chunked_list.py
として保存しますヘッドセクションで、チャンクサイズを設定します。
size = 5
ディレクトリを引数としてスクリプトを実行します。
python3 /path/to/chunked_list.py /path/to/files
次に、(チャンクされた)グループ化された電子メールを使用して、chunked_filename
という名前の各ファイルの編集されたファイルを作成します。
スクリプトは、次のようなファイルを含むディレクトリを入力として受け取ります。
email1@domain1
email2@domain1
email3@domain2
email4@domain1
email5@domain1
email6@domain2
email7@domain1
email8@domain2
email9@domain1
email10@domain2
email11@domain1
各ファイルについて、次のようなコピーを作成します。
domain1,email1@domain1,email2@domain1,email4@domain1
domain1,email5@domain1,email7@domain1,email9@domain1
domain1,email11@domain1
domain2,email3@domain2,email6@domain2,email8@domain2
domain2,email10@domain2
(cunksize = 3に設定)
任意の大きなディレクトリとファイルをサポートするには、 se os.scandir()
ファイルを1つずつ受信し、ファイルを1行ずつ処理します。
#!/usr/bin/env python3
import os
def emails_with_domain(dirpath):
for entry in os.scandir(dirpath):
if not entry.is_file():
continue # skip non-files
with open(entry.path) as file:
for line in file:
email = line.strip()
if email: # skip blank lines
yield email.rpartition('@')[-1], email # domain, email
ドメインごとに電子メールアドレスをグループ化するには、1行に21を超えないようにします。 se collections.defaultdict()
:
import sys
from collections import defaultdict
dirpath = sys.argv[1]
with open('grouped_emails.txt', 'w') as output_file:
emails = defaultdict(list) # domain -> emails
for domain, email in emails_with_domain(dirpath):
domain_emails = emails[domain]
domain_emails.append(email)
if len(domain_emails) == 21:
print(domain, *domain_emails, sep=',', file=output_file)
del domain_emails[:] # clear
for domain, domain_emails in emails.items():
print(domain, *domain_emails, sep=',', file=output_file)
注意: