Bestimmten Ordner in C:\-Verzeichnisbaum finden

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
kodela
User
Beiträge: 185
Registriert: Montag 12. Oktober 2015, 21:24
Wohnort: Landsberg am Lech
Kontaktdaten:

Wie müsste eine if-Bedingung formuliert werden, über die man für einen Dateinamen auch gängige Platzhalter einsetzen kann, zum Beispiel den Stern?

Mit dieser if-Bedingeung

Code: Alles auswählen

if os.path.exists(os.path.join(path, seek_file)):
werden nur Dateien gefunden, die der Vorgabe in seek_file genau entsprechen. Wie müsste diese if-Bedingung umformuliert werden, damit für
seek_file = '*.ts'
alle ts-Dateien gefunden werden?
BlackJack

@kodela: `os.path.exists()` erwartet einen Dateinamen. Da kann man nichts anderes übergeben. Du müsstest also schon die Dateinamen selber prüfen. Falls Du schon Dateinamen hast, schau Dir das `fnmatch`-Modul an, falls Du nur dem Pfad zu den potentiellen Dateien hast, schau Dir das `glob`-Modul an.
kodela
User
Beiträge: 185
Registriert: Montag 12. Oktober 2015, 21:24
Wohnort: Landsberg am Lech
Kontaktdaten:

@BlackJack:
Ich habe den Pfad und experimentiere gerade mit dem glob-Modul, finde aber keine Möglichkeit, damit eine zu "path.exists()" äquivalente Abfrage zu bilden.

Wenn zum Beispiel seek_file = '*.jpg'
bekomme ich für "if glob.glob(seek_file) in path:"
die Fehlermeldung: "TypeError: 'in <string>' requires string as left operand, not list"

Ist mir auch irgend wie klar, dass das nicht funktionieren kann,

Mit "if glob.glob(seek_file) in files:"
werden Dateien, die dem Suchmuster entsprechen (siehe Debugg-Info)

Code: Alles auswählen

base_dir = {str} 'I:\\'
files = {list} ['$IO68QWS.png', '$IXE72K1.jpg', '$RO68QWS.png', '$RXE72K1.jpg', 'desktop.ini']
path = {str} 'I:\\$RECYCLE.BIN\\S-1-5-21-2977881455-1379343495-2050248448-1004'
seek_file = {str} '*.jpg'
spec = {bool} True
subdirs = {list} []
nicht gefunden. Eine Fehlermeldung kommt allerdings nicht. Wie bekomme ich das hin, kannst Du mir einen Fingerzeig geben?
BlackJack

@kodela: Schau Dir doch mal das Ergebnis von `glob()` an. Wie sieht das aus wenn das Muster nicht zutrifft, und wie sieht das aus wenn es zutrifft.
kodela
User
Beiträge: 185
Registriert: Montag 12. Oktober 2015, 21:24
Wohnort: Landsberg am Lech
Kontaktdaten:

Hallo @BlackJack:

Damit funktioniert es:

Code: Alles auswählen

import fnmatch


def ifilter_files(base_dir, seek_file, spec=False):
    for path, subdirs, files in os.walk(base_dir):
        if spec:
            for file in files:
                if fnmatch.fnmatch(file, seek_file):
                    yield path
        else:
            if os.path.exists(os.path.join(path, seek_file)):
                yield path
Wenn in den letzten Beispielen dieses Threads beim Aufruf von ifilter_files() für den dritten Parameter "True" übergeben wird, dann werden nun alle Dateien ausgegeben, die dem Suchmuster entsprechen.

Danke für Deine Unterstützung.

MfG, kodela
Benutzeravatar
kbr
User
Beiträge: 1506
Registriert: Mittwoch 15. Oktober 2008, 09:27

kodela hat geschrieben:Etwas möchte ich noch erwähnen. Ich habe diesen Code unter den Versionen 2.7.11 und 3.5 getestet. Dabei stellte ich fest, dass das Skript unter der Version 3.5 um den Faktor 5 schneller ausgeführt wurde (15 Sek. mit 2.7.11 und 3 Sek. mit 3.5). Wie erklärt sich das?
Die Implementierung von os.walk ist in Python 3.5 geändert worden und läuft nun schneller.
BlackJack

@Kodela: Wozu ist die Unterscheidung nötig? Man kann doch auch einfach Namen ohne Platzhalter übergeben.
kodela
User
Beiträge: 185
Registriert: Montag 12. Oktober 2015, 21:24
Wohnort: Landsberg am Lech
Kontaktdaten:

Hallo @BlackJack:

danke, Du hast wie immer Recht, man muss hier nicht "zweigleisig" fahren. Damit sieht der Code für eine universelle Dateisuche so aus:

Code: Alles auswählen

#!/usr/bin/env python35
# coding=utf-8

import os
import fnmatch


def ifilter_files(base_dir, seek_file):
    for path, subdirs, files in os.walk(base_dir):
        for datei in files:
            if fnmatch.fnmatch(datei, seek_file):
                yield path + '\\' + datei


def main():
    base_dir = 'D:\\'
    seek_file = 'vlc.exe'
    dir_name = ''
    gefunden = False
    for dir_name in ifilter_files(base_dir, seek_file):
        if not gefunden:
            print("Anzeige aller Fundstellen für die Datei %s:" % seek_file)
        print(dir_name)
        gefunden = True
    if not gefunden:
        print("Eine Datei \'%s\' wurde nicht gefunden!" % seek_file)


if __name__ == "__main__":
    main()
Und das mit den unterschiedlichen Geschwindigkeiten ist jetzt auch geklärt. Auch für diesen Hinweis danke.

MfG, kodela
Sirius3
User
Beiträge: 18260
Registriert: Sonntag 21. Oktober 2012, 17:20

@kodela: statt Pfade mit + zusammenzusetzen gibt es os.path.join.
kodela
User
Beiträge: 185
Registriert: Montag 12. Oktober 2015, 21:24
Wohnort: Landsberg am Lech
Kontaktdaten:

@Sirius3: Danke
Antworten