我有一个服务器日志文件,链接here
我的目标是找到“有效”的服务器访问,并将有效的顶级域汇总写入输出文件。
输出文件必须是.tsv文件。示例文件已链接here
为了符合所需的输出,我已经将我的正则表达式的结果(肯定还需要一些调整)放到字典词典中。我的问题是通过内部字典键(顶级域)按字母顺序对字典键进行排序,然后对外部字典键(日期)执行相同的操作。另外,我不确定如何在每个键/值对之间隐藏“\ t”字符。
我知道字典是不合格的,我只是难以将数据移动到可排序的格式,然后将输出写入符合示例文件的样式
到目前为止,我已经包含了我的代码:
import re
fhandle=open("access_log.txt", "rU")
access_log=fhandle.readlines()
validfile=open("valid.tsv", "w")
invalidfile=open("invalid.tsv", "w")
valid_list=list()
valid_dict=dict()
invalid_list=list()
#write results into respective log files
for line in access_log:
valid=re.findall(r'(\d+/[a-zA-Z]+/\d+).*?(GET|POST)\s(http://|https://)([a-zA-Z]+)\.(\w+)\.((?<=com)\.[a-zA-Z]+|[a-zA-Z]+).*?(200)', line)
if valid:
date=valid[0][0]
domain=valid[0][5]
#writes results into 2d dcitonary (dictionary of dictonaries)
if date not in valid_dict:
valid_dict[date]={}
else:
if domain in valid_dict[date]:
valid_dict[date][domain]+=1
else:
valid_dict[date][domain]=1
else:
invalid_list.append(line)
for k,v in valid_dict.items():
valid_list.append([k,v])
for key in sorted(valid_dict.iterkeys()):
print key, valid_dict[key]
fhandle.close()
validfile.close()
invalidfile.close()
答案 0 :(得分:1)
你说得对,你不能对字典进行排序。你能用什么代替?也许是一系列钥匙?
通常,在编码时,它有助于从解决方案中向后走。你的目标是写一个总结。您对摘要有什么需求?把它拿出来:
def write_summary(data):
# output summary
print data
现在data
来自哪里?从简单开始,增加复杂性。
答案 1 :(得分:0)
经过一些修补(和睡眠)后,我有一个解决方案,可以创建与示例输出文件完全匹配的输出。
应用正则表达式函数并将有效条目添加到2d字典后,以下代码正确格式化并写入输出文件:
#step 2
#format output file for tsv
#ordered chronologically, with Key:Value pairs orgainzed alphabeticallv by key (Domain Name)
date_workspace=''
domain_workspace=''
for date in sorted(valid_dict.iterkeys()):
date_workspace+=date + "\t"
for domain_name in sorted(valid_dict[date].iterkeys()):
domain_workspace+="%s:%s\t" % (domain_name, valid_dict[date][domain_name])
date_workspace+=domain_workspace
date_workspace+="\n"
domain_workspace=''
# Step 3
# write output
validfile.write(date_workspace)
for line in invalid_list:
invalidfile.write(line)
逐行走......
循环首先将日期值添加到date_workspace,然后立即切换到迭代第二个字典
使用.iterkey()方法使键可排序。我们现在可以将所有key:value对作为字符串附加到domain_workspace,以及制表符,以便创建制表符分隔。
完成此操作后,将我们的data_workspace(包含所有K:V对的字符串)连接到日期变量
最后,我们连接一个换行符并清除domain_workspace,以确保每个日期值都附加了正确的k:v对。在循环结束时,dat_workspace变量看起来像
date_workspace="date\tk:v\tk:v\tk:v\t\ndate\tk:v\tk:v\tk:v\t\n"
它是最漂亮的输出吗?没有。它是否以比一些可用模块更优雅的方式做一些事情?没有。但是,它会创建格式化为示例的确切规范的输出。