2009-07-31 54 views

Respuesta

31

Si estás en * nix, intente ejecutar el siguiente comando:

sort <file name> | uniq 
+10

O simplemente ordene -u –

47

En Unix/Linux, utilice el comando uniq, según la respuesta de David Locke, o sort, de acuerdo con el comentario de William Pursell.

Si necesita un script en Python:

lines_seen = set() # holds lines already seen 
outfile = open(outfilename, "w") 
for line in open(infilename, "r"): 
    if line not in lines_seen: # not a duplicate 
     outfile.write(line) 
     lines_seen.add(line) 
outfile.close() 

Actualización: La combinación sort/uniq va a eliminar duplicados, pero devolver un archivo con las líneas ordenados, los cuales pueden o no ser lo que quieres. La secuencia de comandos de Python anterior no reordenará las líneas, sino que solo colocará duplicados. Por supuesto, para ordenar también el script anterior, simplemente deje fuera el outfile.write(line) y en su lugar, inmediatamente después del bucle, haga outfile.writelines(sorted(lines_seen)).

+0

Debe ejecutar la ordenación antes de ejecutar uniq porque uniq solo eliminará las líneas si son idénticas a la línea anterior. –

+0

Sí, me referí a su respuesta, pero no reiteré que era un género seguido de uniq. –

+6

+1 para esta solución. Una mejora adicional podría ser almacenar la suma md5 de la línea y comparar la suma md5 de la línea actual. Esto debería reducir significativamente los requisitos de memoria. (vea http://docs.python.org/library/md5.html) – joeslice

13
uniqlines = set(open('/tmp/foo').readlines()) 

esto le dará la lista de líneas únicas.

escritura que volver a algún archivo sería tan fácil como:

bar = open('/tmp/bar', 'w').writelines(set(uniqlines)) 

bar.close() 
+2

Es cierto, pero las líneas estarán en un orden aleatorio de acuerdo a cómo hash. –

+4

¿cuál es el problema con las líneas no ordenadas? con respecto a la pregunta aquí ... – marcell

+0

El problema con este código es que después de escribir, y la última línea no tiene un '\ n'. Luego, los resultados de salida tendrán una línea con 2 líneas fusionadas. – wmlynarski

4

conseguir todas sus líneas en la lista y crea un conjunto de líneas y ya está. por ejemplo,

>>> x = ["line1","line2","line3","line2","line1"] 
>>> list(set(x)) 
['line3', 'line2', 'line1'] 
>>> 

y escribir el contenido de nuevo al archivo.

+0

Es cierto, pero las líneas estarán en un orden aleatorio según cómo hash. –

1

Aquí está mi solución

if __name__ == '__main__': 
f = open('temp.txt','w+') 
flag = False 
with open('file.txt') as fp: 
    for line in fp: 
     for temp in f: 
      if temp == line: 
       flag = True 
       print('Found Match') 
       break 
     if flag == False: 
      f.write(line) 
     elif flag == True: 
      flag = False 
     f.seek(0) 
    f.close() 
2

Python trazadores de líneas uno:

python -c "import sys; lines = sys.stdin.readlines(); print ''.join(sorted(set(lines)))" <InputFile> OutputFile 
2

Usted puede hacer:

import os 
os.system("awk '!x[$0]++' /path/to/file > /path/to/rem-dups") 

Aquí se está utilizando bash en Python :)

También tiene otra manera:

with open('/tmp/result.txt') as result: 
     uniqlines = set(result.readlines()) 
     with open('/tmp/rmdup.txt', 'w') as rmdup: 
      rmdup.writelines(set(uniqlines)) 
6

Es un refrito de cuál ya se ha dicho aquí - aquí lo que yo uso.

import optparse 

def removeDups(inputfile, outputfile): 
     lines=open(inputfile, 'r').readlines() 
     lines_set = set(lines) 
     out=open(outputfile, 'w') 
     for line in lines_set: 
       out.write(line) 

def main(): 
     parser = optparse.OptionParser('usage %prog ' +\ 
         '-i <inputfile> -o <outputfile>') 
     parser.add_option('-i', dest='inputfile', type='string', 
         help='specify your input file') 
     parser.add_option('-o', dest='outputfile', type='string', 
         help='specify your output file') 
     (options, args) = parser.parse_args() 
     inputfile = options.inputfile 
     outputfile = options.outputfile 
     if (inputfile == None) or (outputfile == None): 
       print parser.usage 
       exit(1) 
     else: 
       removeDups(inputfile, outputfile) 

if __name__ == '__main__': 
     main() 
0

añadir a la respuesta de @ David Locke, con sistemas * nix puede ejecutar

sort -u messy_file.txt > clean_file.txt 

que creará clean_file.txt la eliminación de duplicados en orden alfabético.

1

Si alguien está buscando una solución que utiliza un hash y es un poco más llamativo, esto es lo que actualmente utilizo:

def remove_duplicate_lines(input_path, output_path): 

    if os.path.isfile(output_path): 
     raise OSError('File at {} (output file location) exists.'.format(output_path)) 

    with open(input_path, 'r') as input_file, open(output_path, 'w') as output_file: 
     seen_lines = set() 

     def add_line(line): 
      seen_lines.add(hash(line)) 
      return line 

     output_file.writelines((add_line(line) for line in input_file 
           if hash(line) not in seen_lines)) 

Esta función no es perfectamente eficiente como el hash se calcula dos veces, sin embargo, , Estoy bastante seguro de que el valor se almacena en caché.

Cuestiones relacionadas