2017-10-19 3 views
2

Ich versuche, Dateien in einem Verzeichnis durch und finde Duplikate und lösche sie. Ich habe 29 000 Dateien im Verzeichnis, so dass eine rohe Gewalt mehr als einen Tag dauern wird.Python Loop von der aktuellen Datei

ich Dateinamen haben, die wie folgt sind:

„some_file_name“ „some-file-name“

So ein Name Unterstrichen hat und der andere hat Striche und manchmal sind sie zwei oder drei Punkte ein Teil.

Wie kann ich meine innere Schleife an der Position der äußeren Schleife im Verzeichnis beginnen lassen und nur die nächsten 10 überprüfen lassen?

Hier mein Brute-Force ist Code:

import glob, os 
os.chdir("C:/Dir/dir") 

for file in glob.glob("*"): 
    temp = file 
    temp = temp.replace("-", " ") 
    temp = temp.replace("_", " ") 

#How do I start this loop where file is currently at and continue for the next 10 files 
for file2 in glob.glob("*"): 
    temp2 = file2 
    temp2 = temp2.replace("-", " ") 
    temp2 = temp2.replace("_", " ") 
    if temp == temp2: 
     os.remove(file2) 
+0

Haben Sie Duplikate von Inhalten oder von ähnlichen finden wollen Name alleine? – Tomalak

+0

Anstatt zweimal zu loopen (temp1 und temp2) haben Sie versucht, eine Datenstruktur (einen Satz oder eine Liste) zu verwenden, um zu verfolgen, welche Dateinamen Sie bereits besucht haben? Auf diese Weise müssen Sie die einzelnen Dateien nur einmal durchlaufen. – pills

Antwort

3

Von dem, was ich aus Ihrer Frage verstehen, wollen Sie ähnlich benannten Dateien aus einem Verzeichnis löschen. Ich denke deine Vorgehensweise ("schau dir die nächsten 10 Dateinamen an oder so") ist zu ungenau und zu kompliziert.

Die Bedingung ist, wenn eine Datei some_file_name und eine Datei some-file-name existieren, löschen Sie eine von ihnen.

Dies kann sehr einfach durch Erstellen einer Liste von Dateinamen und für jeden Eintrag überprüft werden, ob ein Dateiname mit Unterstrichen anstelle von Bindestrichen auch vorhanden ist und wenn ja, löschen Sie es.

Das folgende verwendet eine set, um dies zu tun, da Sätze sehr gute Nachschlageeigenschaften haben, d. H. some_value in some_set ist viel schneller als es mit Listen wäre. Es vermeidet auch exzessive Datei-Existenztests (wie das Aufrufen von os.path.isfile(file)), da wir bereits alle Dateien kennen, die beim Erstellen des Sets existieren.

import glob, os 

filenames = {file for file in glob.glob(r"C:\Dir\dir\*")} 

for file in filenames: 
    delete_candidate = file.replace("-", "_") 
    if delete_candidate != file and delete_candidate in filenames: 
     os.remove(delete_candidate) 
     print("deleted " + delete_candidate) 

{x for x in iterable} ist ein Satz Verständnis, es baut einen Satz aus einer Liste von Werten. Es funktioniert genau wie Listenergänzungen.

+0

Verwenden Sie '{}' für Satzverständnis, Sie erstellten einen Generator – Uriel

+0

D'oh. Na sicher. – Tomalak

+0

Danke, ich fühle mich jetzt ein bisschen albern. Es ist eigentlich eine sehr einfache Lösung, danke trotzdem, es funktioniert! – user3918910

0

Sie ein Wörterbuch verwenden könnte und setzen Sie den „einfachen Namen“ (ohne _ oder -) als Schlüssel und alle realen Dateinamen als Werte:

import glob, os 

def extendDictValue(dDict, sKey, uValue): 
    if sKey in dDict: 
     dDict[sKey].append(uValue) 
    else: 
     dDict[sKey] = [uValue] 


os.chdir("C:/Dir/dir") 
filenames_dict = {} 
for filename in glob.glob("*"): 
    simple_name = filename.replace("-", " ").replace("_", " ") 
    extendDictValue(filenames_dict, simple_name, filename) 

for simple_name, filenames in filenames_dict.items(): 
    if len(filenames) > 1: 
     filenames.pop(0) 
     for filename in filenames: 
      os.remove(filename)