Seite 1 von 1

Dateipfad einer einzigen Datei ermitteln (os.walk?)

Verfasst: Freitag 26. Juli 2019, 11:40
von NoPy
Hi,

ich muss in einer DB den Dateinamen hinsichtlich Groß- Klein- Schreibung korrigieren.
Gibt es da schon was oder muss man os.walk vergewaltigen? Ich will die Datei nicht öffnen müssen, das kostet zu viel Zeit.

eigentlich benötige ich eine Funktion a la

Code: Alles auswählen

def KorrekterDateiname(AlterDateiName):
    return NeuerDateiName
    
a = 'C:\\irgendwie\\GESCHRIEBEN\\DaTeInAmE.tXt'
b = KorrekterDateiname(a)
print (b)
'C:\\Irgendwie\\Geschrieben\\DateiName.TXT'
Hat jemand eine Idee?

Re: Dateipfad einer einzigen Datei ermitteln (os.walk?)

Verfasst: Freitag 26. Juli 2019, 12:08
von pillmuncher
Was wäre denn in dem Kontext die korrekte Schreibweise für zB. "expertsexchange"?

Re: Dateipfad einer einzigen Datei ermitteln (os.walk?)

Verfasst: Freitag 26. Juli 2019, 12:15
von NoPy
Das weiß eben nur das Dateiverzeichnis :(

also wenn auf dem Datenträger die Datei zu finden ist unter

D:\Hallo\Welt\IrgendeineDatei.TXT

dann soll ein Funktionsaufruf F(d:\hallo\WELT\irgendeinedatei.txt) eben das liefern

Re: Dateipfad einer einzigen Datei ermitteln (os.walk?)

Verfasst: Freitag 26. Juli 2019, 12:22
von sparrow
Ich verstehe das Problem nicht. Seit wann sind Windows-Dateisysteme case-sensitive?

Re: Dateipfad einer einzigen Datei ermitteln (os.walk?)

Verfasst: Freitag 26. Juli 2019, 12:36
von NoPy
Wer spricht von Windows? Du meinst, wegen "C:"
Falls es Dir für das Verständnis hilft:

DIe Dateien liegen auf einem Linux- System (das für mein Windows als "X:" angebunden ist).
Der Dienst, der die Dateien ausliefert, schaut in die eine DB und holt dort den Dateinamen raus. Dort ist aber hinsichtlich der Groß- Klein- Schreibung "Unordnung", da die Daten ursprünglich über einen Windows- Client gelesen wurden. Und damit findet der Dienst die Dateien nicht.

Also muss ich letzlich etwas in der Form (pseudo)

Code: Alles auswählen

SELECT DATEINAME FROM TABELLEXY WHERE ID = 12345;
NeuerDateiname = ErmittleKorrektenDateinamen(DATEINAME) 
UPDATE TABELLEXY SET DATEINAME = NeuerDateiname WHERE ID = 12345
anstellen

Re: Dateipfad einer einzigen Datei ermitteln (os.walk?)

Verfasst: Freitag 26. Juli 2019, 13:06
von __blackjack__
@NoPy: Man könnte mit `pathlib.Path` und der `glob()`-Methode ein Wörterbuch (`dict`) erstellen das alle Pfade/Dateinamen in Kleinbuchstaben umgewandelt auf den tatsächlichen Pfad/Dateinamen abbildet. Und dann kannst Du die Namen aus der Datenbank in Kleinbuchstaben gewandelt dazu verwenden um den tatsächlichen Namen in dem Wörterbuch nachzuschlagen.

Re: Dateipfad einer einzigen Datei ermitteln (os.walk?)

Verfasst: Freitag 26. Juli 2019, 13:42
von sparrow
Witziges Verhalten von glob unter Windows:

Code: Alles auswählen

>>> os.listdir("d:\\test")
['cAmel.TxT']
>>> p = Path("d:\\test")
>>> [e for e in p.glob("*")]
[WindowsPath('d:/test/cAmel.TxT')]
>>> [e for e in p.glob("camel.txt")]
[WindowsPath('d:/test/camel.txt')]
>>> [e for e in p.glob("CAMEL.TXT")]
[WindowsPath('d:/test/camel.txt')]

Re: Dateipfad einer einzigen Datei ermitteln (os.walk?)

Verfasst: Freitag 26. Juli 2019, 14:06
von NoPy
__blackjack__ hat geschrieben: Freitag 26. Juli 2019, 13:06 @NoPy: Man könnte mit `pathlib.Path` und der `glob()`-Methode ein Wörterbuch (`dict`) erstellen das alle Pfade/Dateinamen in Kleinbuchstaben umgewandelt auf den tatsächlichen Pfad/Dateinamen abbildet. Und dann kannst Du die Namen aus der Datenbank in Kleinbuchstaben gewandelt dazu verwenden um den tatsächlichen Namen in dem Wörterbuch nachzuschlagen.
Tatsächlich mach ich das gerade, mit os.walk (als workaround, allerdings ist das Verhalten auch nicht immer so, wie ich es erwarte).

Das Problem: Um den korrekten Pfad weniger Dateien zu ermitteln, muss ich erst das komplette Verzeichnis einlesen, was mehrere Minuten dauert.
Für einen Prozess, der gelegentlich läuft, ist das natürlich akzeptabel, aber um auf die Schnelle für wenige Dateien die Prüfung durchzuführen, ist das schwierig zu vermitteln.
sparrow hat geschrieben: Freitag 26. Juli 2019, 13:42 Witziges Verhalten von glob unter Windows:
Muss ich ausprobieren.

Aber irgendetwas, wie

Code: Alles auswählen

f = AttachFile('c:\\CaMeL.TxT')
print (f.filename)
gibt es anscheinend nicht?

Re: Dateipfad einer einzigen Datei ermitteln (os.walk?)

Verfasst: Freitag 26. Juli 2019, 14:24
von sparrow
Das sollte dein Problem lösen:

Code: Alles auswählen

from pathlib import Path

def get_casesensitive_path(directory, filename):
    path = Path(directory)
    hits = [e for e in path.glob(filename)]
    if len(hits) == 1:
        return hits[0].resolve()
    # TODO: What if the hit is not exactly 1?


print(get_casesensitive_path("d:\\test", "camel.txt"))
# D:\TEST\cAmel.TxT 

Re: Dateipfad einer einzigen Datei ermitteln (os.walk?)

Verfasst: Freitag 26. Juli 2019, 14:35
von NoPy
sparrow hat geschrieben: Freitag 26. Juli 2019, 14:24 Das sollte dein Problem lösen:

Code: Alles auswählen

from pathlib import Path

def get_casesensitive_path(directory, filename):
    path = Path(directory)
    hits = [e for e in path.glob(filename)]
    if len(hits) == 1:
        return hits[0].resolve()


print(get_casesensitive_path("d:\\test", "camel.txt"))
# D:\TEST\cAmel.TxT 
HA! Witzige Sache :)
Jetzt erhalte ich
\\unsere.url.de\irgendeinVerzeichnis\DasIchNichtKenne\DasBasisVerzeichnisDasIchKenne\UndAllesSchoenGroszKlein\Datei.txt

Damit kann ich auf alle Fälle umgehen, vielen Dank!

Re: Dateipfad einer einzigen Datei ermitteln (os.walk?)

Verfasst: Freitag 26. Juli 2019, 21:14
von sparrow
Das wäre eine Alternative, bei der man ausnutzt, dass .glob die Großschreibung behält, wenn man den Joker verwendet. Aber dann kann tatsächlich mehr als ein File getroffen werden:

Code: Alles auswählen

from pathlib import Path

def get_casesensitive_path(directory, filename):
    path = Path(directory)
    hits = [e for e in path.glob(f"{filename}*")]
    if len(hits) == 1:
        return hits[0]
    else:
        raise Exception(f"'{filename}' hits not exactly one file: {hits}")


print(get_casesensitive_path("d:\\test", "camel.txt"))

Re: Dateipfad einer einzigen Datei ermitteln (os.walk?)

Verfasst: Freitag 26. Juli 2019, 21:26
von __blackjack__
@sparrow: Man sollte da vielleicht aus `hits` noch die Ergebnisse rausfiltern die eine andere Länge als `filename` haben, denn wenn man damit nach `test.py` sucht und eine `test.pyc` im gleichen Ordner liegt, dann hat man ganz sicher mehr als einen Treffer, aber der falsche lässt sich leicht an der Länge identifizieren.

Re: Dateipfad einer einzigen Datei ermitteln (os.walk?)

Verfasst: Montag 29. Juli 2019, 07:00
von Sirius3
@sparrow: LCs, die nichts anders machen, als einen Iterator abzulaufen, kann man einfacher als list()-Aufruf ausdrücken.
Oder eben __blackjacks__ Hinweis folgende:

Code: Alles auswählen

return min(path.glob(f"{filename}*"), key=len))
Oder um nur ein Ergebnis zu bekommen, kann man mit Zeichengruppen arbeiten:

Code: Alles auswählen

return next(path.glob(f"{filename[:-1]}[{filename[-1]}]")))

Re: Dateipfad einer einzigen Datei ermitteln (os.walk?)

Verfasst: Montag 29. Juli 2019, 16:49
von NoPy
Vielen Dank für Eure Antworten. Glücklicherweise spielen Joker bei mir keine Rolle. Theoretisch könnte jemand "stänkern", aber dann würde im Zweifelsfall einfach keine Korrektur stattfinden. Also insofern: Fertig