我有2个大型日志文件。我想看看设备是否在b而不是b,反之亦然(排除设备常见的行)文件看起来像这个例子。
04/09 / 2010,13:11:52,Authen OK,user1,默认组,00-24-2B-A1-08-88,29,10.1.1.1,(默认),,, ,,, 13,EAP-TLS ,, DEVICE1,
04/19 / 2010,15:35:24,Authen OK,user2,默认组,00-24-2B-A1-05-EA,29,10.1.1.2,(默认),,,,,, 13,EAP -TLS ,,装置2,
04/09 / 2010,13:11:52,Authen OK,user3,默认组,00-24-2B-A1-08-88,29,10.1.1.3,(默认),,,,,, 13,EAP -TLS ,,设备3,
04/19 / 2010,15:35:24,Authen OK,user4,默认组,00-24-2B-A1-05-EA,29,10.1.1.4,(默认),,,,,, 13,EAP -TLS ,, device4,
重申一下,我需要设备(字段[-2])和IP(字段[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]
答案 0 :(得分: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,这些项目具有类似属性。请注意,这在Python 2.x中称为dict.viewitems( )
。
答案 1 :(得分:0)
第9行中有一个错误,你正在做='。'。join(line)而不是=','。join(line),即引号中的一个点而不是一个逗号。或者也许chbs中的行应该用点分割而不是以后用逗号分隔。
目前如果device7有三行是chbs而不是chst,脚本会告诉你三次,但你对问题的描述意味着你不需要知道它出现了多少次。你真的想要那个或者单个报告可以多次出现吗?在这种情况下,您可以通过仅使用设备名称作为字典键并检查其他字典是否具有该键来简化它。
此刻,您正在记录行号,但并未真正使用它们。如果您确实需要知道设备出现的次数,为什么不报告而不必计算它们?在这种情况下,在向字典添加设备密钥时,首先检查它是否已经存在,如果是,则增加计数器(可能在另一个字典中也由设备名称键入)。