130834
Goto Top

Chaos mit Listen

Hallo liebe Administratoren.

Ich versuche gerade rekursive Datei-Suche mit Ordner-Ausschließung zu programmieren.


Das scheint mit os.walk so weit zu funktionieren. Nur ein Problem:
Verwende ich in der exclude-Liste 1 Element, wird dieses erfolgreich gefiltert.
Verwende ich mehrere, funktioniert gar nichts, d.h. alle Ordner werden genommen.

Der Code sieht wie folgt aus:

# Die Liste mit den ordner die ich filtern möchte.
exclude = ["microsoft", "windows", "recycle", "program", "appdata"]  

# Unkommentiert man die Linie unter dieser, funktioniert es. Lässt man es wie es gerade ist, wird kein Ordner gefiltert.
# exclude = ["program"] 
# Liste mit Datei-Endungen.
exts = ['.txt', '.png']  
# Loop mit der Ausgabe von einem os.walk durch C
for root, dirs, files in os.walk("C:\\", topdown=True, followlinks=False):  
    # Der Filter für die Ordner
    dirs[:] = [dir for dir in dirs if any(excl.upper() not in dir.upper() for excl in exclude)]
    # Datei-Filter ( funktioniert soweit )
    files = [ file for file in files if file.endswith(tuple(exts)) ]
    # Ausgabe in die Konsole schreiben.
    for file in files:
        print(os.path.join(root, file +"\n"))  

sources verwendet:
python - exclude directories in os.walk


Jemand ne Idee was ich da falsch gemacht habe?

danke im vorraus,
lg clragon

Content-Key: 366889

Url: https://administrator.de/contentid/366889

Ausgedruckt am: 28.03.2024 um 21:03 Uhr

Mitglied: colinardo
colinardo 04.03.2018 aktualisiert um 15:25:01 Uhr
Goto Top
Servus,
schreibe die Filter Zeile 11 so:
dirs[:] = [dir for dir in dirs if dir.upper() not in (ex.upper() for ex in exclude)]
Wobei ich natürlich die Subliste
(ex.upper() for ex in exclude)
vorher noch in eine Variable schreiben würde, so dass sie nicht bei jedem Schleifenaufruf erneut erstellt werden muss.

Grüße Uwe
Mitglied: 130834
130834 04.03.2018 um 15:27:43 Uhr
Goto Top
Das wäre einen nette Lösung nur leider hatte ich die schon. Das Problem dabei ist, das die Liste exclude nur Bruchstücke der Wörter enthält um breiter zu filtern. Zum Beispiel, steht nur "Program" drin und nicht "Program Files (x86)".
Diese Linie hatte ich schon und soweit ich weiß würde es dann nur noch funktionieren wenn dir == any(exclude), also exakter match.

lg clragon
Mitglied: colinardo
Lösung colinardo 04.03.2018 aktualisiert um 16:36:34 Uhr
Goto Top
Zitat von @130834:

Das wäre einen nette Lösung nur leider hatte ich die schon. Das Problem dabei ist, das die Liste exclude nur Bruchstücke der Wörter enthält um breiter zu filtern. Zum Beispiel, steht nur "Program" drin und nicht "Program Files (x86)".
Diese Linie hatte ich schon und soweit ich weiß würde es dann nur noch funktionieren wenn dir == any(exclude), also exakter match.
Wenn diese doch nicht ganz unwichtige Anforderung in deinem Post auch direkt gestanden hätte, hätte ich dir auch direkt die passende Lösung bringen können face-wink
Hiermit können deine Such-Strings im Array "exclude" Regex-Patterns sein
import os, re
# Die Liste mit den ordner die ich filtern möchte.
exclude = ["microsoft", "windows", "recycle", "program", "appdata"]  
    
# Liste mit Datei-Endungen.
exts = ['.txt', '.png']  
# Loop mit der Ausgabe von einem os.walk durch C
for root, dirs, files in os.walk("A:\\quelle", topdown=True, followlinks=False):  
    # Der Filter für die Ordner
    dirs[:] = filter(lambda x : not re.search("|".join(exclude),x,re.IGNORECASE) , dirs)  
    # Datei-Filter
    files = [ file for file in files if file.endswith(tuple(exts)) ]
    # Ausgabe in die Konsole schreiben.
    for file in files:
        print(os.path.join(root, file +"\n"))  
Mitglied: colinardo
Lösung colinardo 04.03.2018 aktualisiert um 16:41:19 Uhr
Goto Top
Alternativ wenn die Suchworte keine Regex-Patterns beinhalten sollen (Falls ein nicht Regex affiner User diese Liste erstellt) dann schreibe die Filterzeile 11 so:
dirs[:] = filter(lambda x : not re.search("|".join([re.escape(ex) for ex in exclude]),x,re.IGNORECASE) , dirs)  

Gibt bestimmt noch diverse andere Lösungen, aber ich mache derzeit nicht so viel mit Python.
Mitglied: 130834
130834 04.03.2018 aktualisiert um 16:49:16 Uhr
Goto Top
Muss sagen das mit dem CheckExclude hat auch schon gut funktioniert, viele dank das du dir soviel Mühe machst.

Ich schau's mir mal an. Sehe nicht warum man kein Regex verwenden sollte, mal davon abgesehen das es recht schnell ziemlich kompliziert werden kann.

Wie auch immer, nochmals vielen dank für die Lösung. funktioniert alles wie geplant soweit.

Ach ja, entschuldige mich, das ich das nicht erwähnt habe. Ich habe mir irgendwie noch gedacht das wäre eventuell noch wichtig, bin dann aber nicht zurück gegangen um es reinzueditieren...

lg clragon