Quickly find differences between two large text files

I have two 3GB text files, each file has around 80 million lines. And they share 99.9% identical lines (file A has 60,000 unique lines, file B has 80,000 unique lines).

How can I quickly find those unique lines in two files? Is there any ready-to-use command line tools for this? I'm using Python but I guess it's less possible to find a efficient Pythonic method to load the files and compare.

Any suggestions are appreciated.

10
задан jack 23 August 2010 в 02:17
поделиться

5 ответов

Если порядок имеет значение, попробуйте утилиту comm . Если порядок не имеет значения, отсортировать файл1 файл2 | uniq -u .

7
ответ дан 3 December 2019 в 23:48
поделиться

Если я правильно понял, вам нужны строки этих файлов без дубликатов. Это выполняет свою работу:

uniqA = set(open('fileA', 'r'))
1
ответ дан 3 December 2019 в 23:48
поделиться

Python имеет diffflib, который утверждает, что вполне конкурентоспособен с другими утилитами diff, см.: http://docs.python.org/library/difflib.html

0
ответ дан 3 December 2019 в 23:48
поделиться

Я думаю, что это самый быстрый метод (будь то Python или другой язык, IMO не имеет большого значения).

Примечания:

1. Я сохраняю хэш каждой строки только для экономии места (и времени, если может происходить разбиение на страницы)

2. Из-за вышеизложенного я распечатываю только номера строк; если вам нужны настоящие строки, вам просто нужно снова прочитать файлы

3. Я предполагаю, что хеш-функция не приводит к конфликтам. Это почти, но не совсем точно.

4. Я импортирую hashlib, потому что встроенная функция hash () слишком коротка, чтобы избежать конфликтов.

import sys
import hashlib

file = []
lines = []
for i in range(2):
    # open the files named in the command line
    file.append(open(sys.argv[1+i], 'r'))
    # stores the hash value and the line number for each line in file i
    lines.append({})
    # assuming you like counting lines starting with 1
    counter = 1
    while 1:
        # assuming default encoding is sufficient to handle the input file
        line = file[i].readline().encode()
        if not line: break
        hashcode = hashlib.sha512(line).hexdigest()
        lines[i][hashcode] = sys.argv[1+i]+': '+str(counter)
        counter += 1
unique0 = lines[0].keys() - lines[1].keys()
unique1 = lines[1].keys() - lines[0].keys()
result = [lines[0][x] for x in unique0] + [lines[1][x] for x in unique1]
3
ответ дан 3 December 2019 в 23:48
поделиться

Имея 60 000 или 80 000 уникальных строк, вы можете просто создать словарь для каждой уникальной строки, сопоставив его с числом. mydict ["hello world"] => 1 и т. Д. Если ваша средняя строка составляет около 40-80 символов, это будет около 10 МБ памяти.

Затем прочтите каждый файл, преобразовав его в массив чисел через словарь. Они легко помещаются в память (2 файла по 8 байтов * 3 ГБ / 60 КБ строк меньше 1 МБ памяти). Затем сравните списки. Вы можете инвертировать словарь и использовать его для печати текста различающихся строк.

РЕДАКТИРОВАТЬ:

В ответ на ваш комментарий вот пример сценария, который присваивает номера уникальным строкам при чтении из файла.

#!/usr/bin/python

class Reader:

    def __init__(self, file):
        self.count = 0
        self.dict = {}
        self.file = file

    def readline(self):
        line = self.file.readline()
        if not line:
            return None
        if self.dict.has_key(line):
            return self.dict[line]
        else:
            self.count = self.count + 1
            self.dict[line] = self.count
            return self.count

if __name__ == '__main__':
    print "Type Ctrl-D to quit."
    import sys
    r = Reader(sys.stdin)
    result = 'ignore'
    while result:
        result = r.readline()
        print result
2
ответ дан 3 December 2019 в 23:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: