python анализирует 2 файла журнала - PullRequest
2 голосов
/ 11 августа 2010

У меня есть 2 больших файла журнала.Я хочу видеть, находится ли устройство в a, но не в 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 ,, device2,
04/09 / 2010,13: 11: 52, Authen OK, user3, группа по умолчанию, 00-24-2B-A1-08-88,29,10.1.1.3, (по умолчанию) ,,,,,, 13, EAP-TLS ,, device3,
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, но не 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]

Ответы [ 2 ]

1 голос
/ 11 августа 2010

Вы ищете симметричную разность :

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 свойства. Обратите внимание, что это называется dict.viewitems( ) в Python 2.x.

0 голосов
/ 11 августа 2010

В строке 9 есть ошибка, когда вы делаете = '.'. Join (строка) вместо = ','. Join (строка), то есть точка в кавычках вместо запятой.Или, может быть, строки в chbs следует разбить на точки вместо запятых позже.

В настоящий момент, если есть три строки для device7, это chbs, но не chst, скрипт скажет вам три раза, но ваше описаниепроблема подразумевает, что вам не нужно знать, сколько раз он появляется.Вы действительно этого хотите или один отчет подходит для нескольких случаев?В этом случае вы можете упростить его, просто используя имя устройства в качестве ключа словаря и проверив, есть ли у другого словаря этот ключ.

Также в данный момент вы записываете номера строк, но на самом деле их не используете,Если вам нужно знать, сколько раз появляется устройство, почему бы не сообщить об этом вместо того, чтобы считать их?В этом случае при добавлении ключа устройства в словарь сначала проверьте, существует ли он уже, и если это так, увеличьте счетчик (возможно, в другом словаре, также введенном по имени устройства).

...