2

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

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,(Default),,, ,,,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,

重申一下,我需要设备(字段 [-2])和 IP(字段 [7])用于日志文件 a 但不在 b 中,在 b 但不在 a 中的每个设备

这是我到目前为止所做的,但看起来有点笨重而且非常慢(每个文件大约有 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]
4

2 回答 2

1

您正在寻找对称差异

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( )返回了具有 setlike 属性的项目的视图。请注意,这是dict.viewitems( )在 Python 2.x中调用的。

于 2010-08-11T08:42:31.940 回答
0

第 9 行有一个错误,您正在执行 ='.'.join(line) 而不是 =','.join(line) 即引号中的点而不是逗号。或者也许 chbs 中的行以后应该用点而不是逗号分割。

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

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

于 2010-08-11T09:14:55.783 回答