Как из большого log файла убрать повторы строк?

Мучаюсь с регулярными выражениями уже второй день, ничего не получается. В программировании полный ноль. Как из файла с миллионом строк убрать строки повторы со второго столбика, пишу ACL, в ручную фильтровать очень долго(

Пример:

permitted tcp 10.10.20.51(53840) -> 10.10.0.2(389), 1 packet
permitted tcp 10.10.20.150(28426) -> 10.10.0.5(8080), 1 packet
permitted tcp 10.10.20.54(53460) -> 10.10.0.2(389), 1 packet
permitted tcp 10.10.20.54(53462) -> 10.10.0.3(389), 1 packet
permitted udp 10.10.20.54(53793) -> 10.10.0.3(53), 1 packet
permitted tcp 10.10.20.54(53464) -> 10.10.0.5(8080), 1 packet

А в результате хочется

permitted tcp 10.10.20.51(53840) -> 10.10.0.2(389), 1 packet
permitted tcp 10.10.20.150(28426) -> 10.10.0.5(8080), 1 packet
permitted tcp 10.10.20.54(53462) -> 10.10.0.3(389), 1 packet
permitted udp 10.10.20.54(53793) -> 10.10.0.3(53), 1 packet

Ответы (1 шт):

Автор решения: Stanislav Volodarskiy

Пробегаем по строкам файла. Файл будем подавать через стандартный вход. Запускать как-то так: python filter_duplicates.py < input.txt > output.txt. Пока это простое копирование:

for line in sys.stdin:
    print(line, end='')

В строках нужно выделить ключи - те части которые мы будем сравнивать для поиска повторений. Я думаю что сравнивать нужно от стрелочки и до конца строки. ->.* отыскивает стрелочку. .* означает "и любые символы". assert ломает программу если стрелочки в строке нет. Последняя строка выделяет "от стрелочки до конца":

m = re.search('->.*', line)
assert m is not None
key = m.group(0)

Ключи надо проверять на повторение. Заведем keys - хранилище для ключей, которые мы уже видели. if key not in keys: - проверяет что нового ключа там нет. Если это так, печатаем строку и запоминаем ключ на будущее:

keys = set()
...

    if key not in keys:
        print(line, end='')
        keys.add(key)

Всё вместе:

import re
import sys

keys = set()

for line in sys.stdin:
    m = re.search('->.*', line)
    assert m is not None
    key = m.group(0)
    if key not in keys:
        print(line, end='')
        keys.add(key)
$ cat input.txt 
permitted tcp 10.10.20.51(53840) -> 10.10.0.2(389), 1 packet
permitted tcp 10.10.20.150(28426) -> 10.10.0.5(8080), 1 packet
permitted tcp 10.10.20.54(53460) -> 10.10.0.2(389), 1 packet
permitted tcp 10.10.20.54(53462) -> 10.10.0.3(389), 1 packet
permitted udp 10.10.20.54(53793) -> 10.10.0.3(53), 1 packet
permitted tcp 10.10.20.54(53464) -> 10.10.0.5(8080), 1 packet

$ python filter_duplicates.py < input.txt 
permitted tcp 10.10.20.51(53840) -> 10.10.0.2(389), 1 packet
permitted tcp 10.10.20.150(28426) -> 10.10.0.5(8080), 1 packet
permitted tcp 10.10.20.54(53462) -> 10.10.0.3(389), 1 packet
permitted udp 10.10.20.54(53793) -> 10.10.0.3(53), 1 packet

Проверим на файле из миллиона строк:

$ wc -lc long_input.txt 
 1000000 77000000 long_input.txt

$ time python filter_duplicates.py < long_input.txt > long_output.txt

real  0m1.788s
user  0m1.736s
sys   0m0.048s

$ wc -lc long_output.txt 
  99998 7699846 long_output.txt
→ Ссылка