Encuentra rápidamente las diferencias entre dos archivos de texto grandes

Tengo dos archivos de texto de 3GB, cada archivo tiene alrededor de 80 millones de líneas. Y comparten 99,9% de líneas idénticas (el archivo A tiene 60,000 líneas únicas, el archivo B tiene 80,000 líneas únicas).

¿Cómo puedo encontrar rápidamente esas líneas únicas en dos archivos? ¿Hay alguna herramienta de línea de comandos lista para usar para esto? Estoy usando Python, pero creo que es menos posible encontrar un método Pythonic eficiente para cargar los archivos y comparar.

Cualquier sugerencia es apreciada.

Si el orden importa, pruebe la utilidad de comm . Si el orden no importa, sort file1 file2 | uniq -u sort file1 file2 | uniq -u .

Creo que este es el método más rápido (ya sea en Python u otro idioma no debería importar demasiado IMO).

Notas:

1. Solo almaceno el hash de cada línea para ahorrar espacio (y tiempo si puede ocurrir la paginación)

2.Debido a lo anterior, solo imprimo números de línea; Si necesita líneas reales, solo tendrá que volver a leer los archivos.

3. Supongo que la función hash no genera conflictos. Esto es casi, pero no perfectamente, cierto.

4. Importe hashlib porque la función hash () incorporada es demasiado corta para evitar conflictos.

 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] 

Con 60,000 u 80,000 líneas únicas, simplemente puede crear un diccionario para cada línea única, asignándola a un número. mydict["hello world"] => 1 , etc. Si su línea promedio es de alrededor de 40-80 caracteres, será aproximadamente 10 MB de memoria.

Luego lea cada archivo y conviértalo en una serie de números a través del diccionario. Esos cabrán fácilmente en la memoria (2 archivos de 8 bytes * 3GB / 60k líneas es menos de 1 MB de memoria). Luego difunde las listas. Podría invertir el diccionario y usarlo para imprimir el texto de las líneas que difieren.

EDITAR:

En respuesta a su comentario, aquí hay una secuencia de comandos de muestra que asigna números a líneas únicas a medida que se lee desde un archivo.

 #!/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 

Si entiendo correctamente, querrás las líneas de estos archivos sin duplicados. Esto hace el trabajo:

 uniqA = set(open('fileA', 'r')) 

http://www.emeditor.com/ puede manejar archivos grandes y también puede compararlos.

Python tiene un difflib que dice ser bastante competitivo con otras utilidades de dif, consulte: http://docs.python.org/library/difflib.html