2010-08-11 91 views
2

我有2个大型日志文件。我想查看一个设备是否在a而不是b,反之亦然(排除设备常见的行),这些文件看起来就像这个例子。python分析2日志文件

04/09/2010,13:11:52,Authen OK,user1,Default Group,00-24-2B-A1-08-88,29,10.1.1.1,(Default),,,, ,13,EAP-TLS ,, device1,
04/19/2010,15:35:24,Authen OK,user2,Default Group,00-24-2B-A1-05-EA,29,10.1.1.2 ,(默认),,,,,, 13,EAP-TLS ,, device2,
04/09/2010,13:11:52,Authen OK,user3,Default Group,00-24-2B-A1-08 -88,29,10.1.1.3,(默认),,,,,, 13,EAP-TLS ,, device3,
04/19/2010,15:35:24,Authen OK,user4,Default Group,00 -24-2B-A1-05-EA,29,10.1.1.4,(默认),,,,,, 13,EAP-TLS ,, device4,

重申,我需要device(field [ 2])和IP(f ield [7])对于日志文件中的每个设备a但不是b,并且在b中但不是

以下是我迄今为止所做的,但似乎有点笨拙并且非常慢(每个文件都有约400K行)。我交叉两次。任何人都可以提出效率吗?也许我正在使用错误的逻辑?

chst={} 
chbs={} 
for i,line in enumerate(open('chst.txt').readlines()): 
    line=line.split(',') 
    chst[line[-2]+','+str(i)]=','.join(line) 

for i,line in enumerate(open('chbs.txt').readlines()): 
    line=line.split(',') 
    chbs[line[-2]+','+str(i)]='.'.join(line) 

print "these lines are in CHST but not in CHBS" 
for a in chst: 
    if a.split(',')[0] not in str(chbs.values()): 
     line=chst[a].split(',') 
     print line[-2], line[7] 

print "\nthese lines are in CHBS but not in CHST" 

for a in chbs: 
    if a.split(',')[0] not in str(chst.values()): 
     line=chbs[a].split(',') 
     print line[-2], line[7] 

回答

1

你正在寻找一个symmetric difference

chst = { (line.split(",")[ -2 ], line.split(",")[ 7 ]) for line in open(...) } 
chbs = { (line.split(",")[ -2 ], line.split(",")[ 7 ]) for line in open(...) } 

diff = chst^chbs 

如果您需要的不对称差异,请使用-

chst - chbs # tuples in chst but not in chbs 
chbs - chst # tuples in chbs but not in chst 

如果您需要实际的线,而不是一个元组(device, IP)你可以使用字典而不是集合:

chst = { (line.split(",")[ -2 ], line.split(",")[ 7 ]): line for line in open(...) } 
chbs = { (line.split(",")[ -2 ], line.split(",")[ 7 ]): line for line in open(...) } 

diff = chst.items()^bar.items() 

这是可行的,因为dict.items()对项目返回view,项目具有setlike属性。请注意,这在Python 2.x中被称为dict.viewitems()

+0

自Python 2.6以来,sets模块已被弃用。从2.6开始,set和frozensets确实是内置的。 – 2010-08-11 08:52:38

+0

哎呀,后台团队*已经很忙!固定。 – katrielalex 2010-08-11 08:58:15

+0

我也很确定只是调用项目将无法正常工作(并且与dict视图无关) - 您必须在该字典上调用viewitems,从2.7开始支持。 items方法只返回键/值对的列表,而对于列表,不支持^运算符,而viewitems返回dict_ietms类型的实际视图。 – 2010-08-11 09:04:55

0

第9行有一个错误,你在做='。'。join(line)而不是=','。join(line),即引号中的一个点而不是逗号。或者,也许在Chbs中的线条应该在点上而不是以后用逗号分割。

现在,如果device7有三行是chbs而不是chst,脚本会告诉你三次,但是你对问题的描述意味着你不需要知道它出现了多少次。你真的想要这个还是一个单一的报告可以多次发生?在这种情况下,只需使用设备名称作为字典密钥并检查其他字典是否具有该密钥即可简化它。

此刻你正在记录行号,但没有真正使用它们。如果您确实需要知道设备出现多少次,为什么不报告而不是必须对它们进行计数?在这种情况下,当向字典添加设备密钥时,首先检查它是否已经存在,如果是,则增加一个计数器(可能在另一个字典中也由设备名称键入)。

+0

谢谢西蒙,确实是一个错字。无论如何,我的方式太长,所以感谢上面的答案 – Bill 2010-08-11 10:53:54