2009-07-31 16 views

Répondre

31

Si vous êtes sur * nix, essayez d'exécuter la commande suivante:

sort <file name> | uniq 
+10

Ou juste trier -u –

47

Sur Unix/Linux, utilisez la commande uniq, selon la réponse de David Locke, ou sort, selon le commentaire de William Pursell.

Si vous avez besoin d'un script 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() 

Mise à jour: Le sort/uniq combinaison supprimera les doublons mais renvoyer un fichier avec les lignes triées, qui peuvent ou peuvent ne pas être ce que vous voulez. Le script Python ci-dessus ne va pas réorganiser les lignes, mais simplement supprimer les doublons. Bien sûr, pour que le script ci-dessus puisse également être trié, il suffit d'omettre le outfile.write(line) et, immédiatement après la boucle, de faire outfile.writelines(sorted(lines_seen)).

+0

Vous devez exécuter tri avant d'exécuter uniq car uniq ne supprimera les lignes que si elles sont identiques à la ligne précédente. –

+0

Oui - J'ai fait référence à votre réponse, mais je n'ai pas répété que c'était un tri suivi par uniq. –

+6

+1 pour cette solution. Une autre amélioration pourrait consister à stocker la somme md5 de la ligne et à comparer la somme md5 de la ligne courante. Cela devrait réduire considérablement les besoins en mémoire. (Voir http://docs.python.org/library/md5.html) – joeslice

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

cela vous donnera la liste des lignes uniques.

écrit que revenir à un certain dossier serait aussi facile que:

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

bar.close() 
+2

Vrai, mais les lignes seront dans un ordre aléatoire en fonction de leur hachage. –

+4

Quel est le problème avec les lignes qui ne sont pas triées? en ce qui concerne la question ici ... – marcell

+0

Le problème avec ce code est qu'après avoir écrit, et la dernière ligne n'a pas de '\ n'. Ensuite, les résultats de sortie auront une ligne avec 2 lignes fusionnées. – wmlynarski

4

obtenir toutes vos lignes dans la liste et faire un ensemble de lignes et vous avez terminé. par exemple,

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

et écrire le contenu dans le fichier.

+0

Vrai, mais les lignes seront dans un ordre aléatoire en fonction de leur hachage. –

1

Voici ma solution

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 One liners:

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

Vous pouvez faire:

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

Ici Vous utilisez bash en python :)

Vous avez également un autre moyen:

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

Son une resucée de ce qui est déjà dit ici - ici ce que je l'utilise.

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

ajouter à la réponse de Locke @ David, avec les systèmes * nix vous pouvez exécuter

sort -u messy_file.txt > clean_file.txt 

qui va créer clean_file.txt la suppression des doublons dans l'ordre alphabétique.

1

Si quelqu'un est à la recherche d'une solution qui utilise un hachage et est un peu plus flashy, ce que j'utilise actuellement:

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)) 

Cette fonction est parfaitement efficace que le hachage est calculé deux fois, mais , Je suis sûr que la valeur est mise en cache.

Questions connexes