Dateipfad für einen Ordner ausgeben (flexibler Dateipfad zur Auswahl der aktuellsten Datei)

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.
Jghurt
User
Beiträge: 32
Registriert: Samstag 8. Mai 2021, 15:18

Hallo zusammen,

ich habe ein kleines Problem:

Für mein Programm werden Sensordaten aus einer CSV Datei eingelesen. Die CSV Datei liegt nicht bei meinem Skript sondern in einem anderen Verzeichnis.
Dies erfolgt aktuell wie folgt:

Code: Alles auswählen

 path = r'D:\xxxxxx\xxxx\Sensordaten\Messdaten xx.xx.2021\Liste_2021-xx-xx.csv'
Die CSV Datei wird aber ca alle 1-6 Wochen (in unregelmäßigen Abständen) neu abgespeichert. Dadurch muss ich jedesmal im Code den Dateipfad ändern, da die aktuelle CSV Datei jetzt natürlich einen anderen Namen mit einem anderen Datum hat. Die CSV Dateien werden also immer in dem Ordner "Sensordaten" in einem jeweils neuen Ordner "Messdaten xx.xx.2021" abgespeichert. Der Name der csv Datei in diesen Ordnern verändert sich natürlich auch immer. (siehe Beispiel unten)

Gibt es eine Möglichkeit in Python einen Pfad anzugeben, dass aus dem Ordner "Messdaten xx.xx.2021" jeweils aus dem obersten Ordner die erste Datei als Pfad auswählt? Damit hätte ich das Problem gelöst.

Code: Alles auswählen

Ordner 1 (immer gleich)
	Unterordner 1 (aktuellster Ordner)
		Csv Datei 1 (hiervon will ich den Dateipfad angeben)
		Csv Datei 2
	Unterordner 2 (alter Ordner)
		Csv Datei 3
		Csv Datei 4
	Unterordner 3 (alter Ordner)
		Csv Datei 5
		Csv Datei 6		
		
Also dass ich einen Dateipfad angeben kann, dass immer aus Ordner 1, der oberste Ordner (hier Unterordner 1 als Beispiel) und die oberste CSV Datei (hier CSV Datei 1) ausgewählt wird).

An den CSV Dateien kann ich leider nichts ändern, deswegen die Frage, ob man irgendwie einen flexiblen Dateipfad angeben kann.

Danke für Eure Hilfe :)
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@Jghurt,

So bekommst du eine sortierte Liste aller csv-Dateien unter dem Ordner "Messdaten xx.xx.2021".

Code: Alles auswählen

from pathlib import Path

base_path = Path('D:', 'xxxxxx', 'xxxx', 'Sensordaten', 'Messdaten xx.xx.2021')
paths = sorted(base_path.glob("**/*.csv"))
Diese Reihenfolge hängt natürlich von den jeweiligen Pfaden ab. Eventuell musst das noch ein wenig an deine Bedürfnisse anpassen, damit du sicher immer die richtige Datei bekommst.
Zuletzt geändert von rogerb am Freitag 30. Juli 2021, 15:45, insgesamt 1-mal geändert.
Jghurt
User
Beiträge: 32
Registriert: Samstag 8. Mai 2021, 15:18

rogerb hat geschrieben: Freitag 30. Juli 2021, 15:41 @Jghurt,

So bekommst du eine sortierte Liste aller csv-Dateien unter dem Ordner "Messdaten xx.xx.2021".

Code: Alles auswählen

from pathlib import Path

base_path = Path("D:\Projects\PJ01\Sensordaten")
paths = sorted(base_path.glob("**/*.csv"))
Diese Reihenfolge hängt natürlich von den jeweiligen Pfaden ab. Eventuell musst das noch ein wenig an deine Bedürfnisse anpassen, damit du sicher immer die richtige Datei bekommst.
Hallo, vielen Dank für die schnelle Antwort!
Jghurt
User
Beiträge: 32
Registriert: Samstag 8. Mai 2021, 15:18

rogerb hat geschrieben: Freitag 30. Juli 2021, 15:41 @Jghurt,

So bekommst du eine sortierte Liste aller csv-Dateien unter dem Ordner "Messdaten xx.xx.2021".

Code: Alles auswählen

from pathlib import Path

base_path = Path('D:', 'xxxxxx', 'xxxx', 'Sensordaten', 'Messdaten xx.xx.2021')
paths = sorted(base_path.glob("**/*.csv"))
Diese Reihenfolge hängt natürlich von den jeweiligen Pfaden ab. Eventuell musst das noch ein wenig an deine Bedürfnisse anpassen, damit du sicher immer die richtige Datei bekommst.
Ich habe deinen Code probiert und bei mir kommt dann leider immer ein Fehler. Ich habe nun selber eine Lösung gefunden, wie ich den Dateipfad des aktuellsten Ordners herausfinde:

Code: Alles auswählen

import os, glob

folder = max(glob.glob(os.path.join(r'C:\Users\xxx\Desktop\xx\Datenauswertung_CSV', '*/')), key=os.path.getmtime)
wie kriege ich nun jedoch aus diesem Ordner die oberste Datei? Also ich habe jetzt den Dateipfad, in dem die aktuellen CSV Dateien drinne sind. Ich möchte jetzt nur noch die oberste CSV Datei hier auswählen (nicht die zuletzt abgespeicherte/aktuellste)

*Edit 1*
Wenn ich key=os.path.getmtime verwende, wird ja die zuletzt aktualisierte csv Datei genommen.
Wenn ich key=os.path.getctime in dem Ordner verwende, wird mir die richtige csv Datei angezeigt. Ist das Zufall oder richtig so?

*Edit 2*
Mit getctime wird mir ja die Datei ausgegeben, die zuerst erstellt wurde oder?
In meinem Ordner sind 4 CSV Datein, wobei die zuerst erstellte ganz oben ist. Somit müsste ich mit getctime ja IMMER die richtige csv Datei bekommen?

Also getmtime für den zuletzt erstellten Ordner, und im Ordner getctime für die zuerst abgespeicherte Datei dort.
Zuletzt geändert von Jghurt am Freitag 30. Juli 2021, 16:19, insgesamt 2-mal geändert.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@rogerb: ich befürchte ja, dass die xx eigentlich Zahlen sind, und Du daher nach dem falschen Datum die Ordner sortierst, die "Messdaten 31.07.2021" kommen halt lexikalisch vor den "Messdaten 01.08.2021".

Jetzt kann man entweder eine passende Sortierfunktion für die ungünstige Verzeichnisbenennung finden, oder nach der richtigen csv-Dateibenennung sortieren, bzw. da man nur den neusten Eintrag braucht, aus sorted max machen.

Code: Alles auswählen

from pathlib import Path

base_path = Path('D:/xxxxxx/xxxx/Sensordaten')
csv_path = max(base_path.glob("*/Liste_*.csv"), key=lambda p:p.name)
@Jghurt: os und glob sind veraltet, statt dessen benutzt man pathlib.
Was ist denn die genaue Fehlermeldung?
Jghurt
User
Beiträge: 32
Registriert: Samstag 8. Mai 2021, 15:18

Sirius3 hat geschrieben: Freitag 30. Juli 2021, 16:14 @rogerb: ich befürchte ja, dass die xx eigentlich Zahlen sind, und Du daher nach dem falschen Datum die Ordner sortierst, die "Messdaten 31.07.2021" kommen halt lexikalisch vor den "Messdaten 01.08.2021".

Jetzt kann man entweder eine passende Sortierfunktion für die ungünstige Verzeichnisbenennung finden, oder nach der richtigen csv-Dateibenennung sortieren, bzw. da man nur den neusten Eintrag braucht, aus sorted max machen.

Code: Alles auswählen

from pathlib import Path

base_path = Path('D:/xxxxxx/xxxx/Sensordaten')
csv_path = max(base_path.glob("*/Liste_*.csv"), key=lambda p:p.name)
@Jghurt: os und glob sind veraltet, statt dessen benutzt man pathlib.
Was ist denn die genaue Fehlermeldung?
Hallo Sirius, schau dir zu meinem letzten Kommentar *edit 1 und edit 2* an. Ich glaube so könnte ich das Problem lösen.
Inwiefern ist os und glob veraltet, bzw könnte es zu problemen führen?
Jghurt
User
Beiträge: 32
Registriert: Samstag 8. Mai 2021, 15:18

Jghurt hat geschrieben: Freitag 30. Juli 2021, 16:10
rogerb hat geschrieben: Freitag 30. Juli 2021, 15:41 @Jghurt,

So bekommst du eine sortierte Liste aller csv-Dateien unter dem Ordner "Messdaten xx.xx.2021".

Code: Alles auswählen

from pathlib import Path

base_path = Path('D:', 'xxxxxx', 'xxxx', 'Sensordaten', 'Messdaten xx.xx.2021')
paths = sorted(base_path.glob("**/*.csv"))
Diese Reihenfolge hängt natürlich von den jeweiligen Pfaden ab. Eventuell musst das noch ein wenig an deine Bedürfnisse anpassen, damit du sicher immer die richtige Datei bekommst.

Ich habe deinen Code probiert und bei mir kommt dann leider immer ein Fehler. Ich habe nun selber eine Lösung gefunden, wie ich den Dateipfad des aktuellsten Ordners herausfinde:

Code: Alles auswählen

import os, glob

folder = max(glob.glob(os.path.join(r'C:\Users\xxx\Desktop\xx\Datenauswertung_CSV', '*/')), key=os.path.getmtime)
wie kriege ich nun jedoch aus diesem Ordner die oberste Datei? Also ich habe jetzt den Dateipfad, in dem die aktuellen CSV Dateien drinne sind. Ich möchte jetzt nur noch die oberste CSV Datei hier auswählen (nicht die zuletzt abgespeicherte/aktuellste)

*Edit 1*
Wenn ich key=os.path.getmtime verwende, wird ja die zuletzt aktualisierte csv Datei genommen.
Wenn ich key=os.path.getctime in dem Ordner verwende, wird mir die richtige csv Datei angezeigt. Ist das Zufall oder richtig so?

*Edit 2*
Mit getctime wird mir ja die Datei ausgegeben, die zuerst erstellt wurde oder?
In meinem Ordner sind 4 CSV Datein, wobei die zuerst erstellte ganz oben ist. Somit müsste ich mit getctime ja IMMER die richtige csv Datei bekommen?

Also getmtime für den zuletzt erstellten Ordner, und im Ordner getctime für die zuerst abgespeicherte Datei dort.

@Sirius
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn Du ein Datum im Dateinamen hast, würde ich mich nicht auf getctime oder getmtime verlassen. pathlib ist einfach das viel komfortablere Interface als die low-level-Funktionen in os.

Und nochmal die Frage: welche Fehlermeldung bekommst Du mit meinem oder rogerb`s Code?
Jghurt
User
Beiträge: 32
Registriert: Samstag 8. Mai 2021, 15:18

Sirius3 hat geschrieben: Freitag 30. Juli 2021, 16:14 @rogerb: ich befürchte ja, dass die xx eigentlich Zahlen sind, und Du daher nach dem falschen Datum die Ordner sortierst, die "Messdaten 31.07.2021" kommen halt lexikalisch vor den "Messdaten 01.08.2021".

Jetzt kann man entweder eine passende Sortierfunktion für die ungünstige Verzeichnisbenennung finden, oder nach der richtigen csv-Dateibenennung sortieren, bzw. da man nur den neusten Eintrag braucht, aus sorted max machen.

Code: Alles auswählen

from pathlib import Path

base_path = Path('D:/xxxxxx/xxxx/Sensordaten')
csv_path = max(base_path.glob("*/Liste_*.csv"), key=lambda p:p.name)
@Jghurt: os und glob sind veraltet, statt dessen benutzt man pathlib.
Was ist denn die genaue Fehlermeldung?
Da wird mir die Klammer nach dem Wort "Sensordaten'" markiert und es kommt die Fehlermeldung: SyntaxError. (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape.
Jghurt
User
Beiträge: 32
Registriert: Samstag 8. Mai 2021, 15:18

Sirius3 hat geschrieben: Freitag 30. Juli 2021, 17:33 Wenn Du ein Datum im Dateinamen hast, würde ich mich nicht auf getctime oder getmtime verlassen. pathlib ist einfach das viel komfortablere Interface als die low-level-Funktionen in os.

Und nochmal die Frage: welche Fehlermeldung bekommst Du mit meinem oder rogerb`s Code?
Auf das Datum im Dateinamen kann man sich auch nicht verlassen. Teilweise kann es nämlich vorkommen, dass eine CSV Datei am gleichen Tag mehrmals in verschiedenen Ordnern abgespeichert wird. Wieso sollte getmtime denn Probleme machen?

Ich habe jetzt folgende Lösung mit OS gefunden:

Code: Alles auswählen

import os, glob

folder = max(glob.glob(os.path.join(r'C:\Users\xxx\Desktop\xx\Datenauswertung_CSV', '*/')), key=os.path.getmtime)

folder_walk = os.walk(folder)
first_folder_file = next(folder_walk) [2][0]
path = folder + first_folder_file
Damit wird mir die erste Datei im Ordner angezeigt. Was wäre denn an dieser Lösung "schlecht"?
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@Jghurt,
Was wäre denn an dieser Lösung "schlecht"?
Wenn man strings durch "+" zu einem Pfad zusammenfügt, können sich leicht Fehler einschleichen. Linux und Ubuntu verwenden ja zum Beispiel verschiedene Symbole als Pfadtrennzeichen.
Bei pathlib werden diese Probleme komfortabel im Hintergrund gelöst.

Es gibt noch viele Beispiellösungen mit "os" im Internet, da das früher das Mittel der Wahl war. Aber auch die, die diese Lösungen vor einiger Zeit veröffentlicht hatten, würden heute wohl eher pathlib verwenden.
Man muss sich halt umstellen und die neuen Funktionen erstmal lernen.

Hier hätte ich noch eine Lösung, mit pathlib und deiner Sortiermethode:

Code: Alles auswählen

import os
from pathlib import Path

base_path = Path("C:", "Users", "Desktop", "xx", "Datenauswertung_CSV")
csv_files = sorted(base_path.glob("**/*.csv"), key=os.path.getmtime)
Jghurt
User
Beiträge: 32
Registriert: Samstag 8. Mai 2021, 15:18

rogerb hat geschrieben: Freitag 30. Juli 2021, 19:10 @Jghurt,
Was wäre denn an dieser Lösung "schlecht"?
Wenn man strings durch "+" zu einem Pfad zusammenfügt, können sich leicht Fehler einschleichen. Linux und Ubuntu verwenden ja zum Beispiel verschiedene Symbole als Pfadtrennzeichen.
Bei pathlib werden diese Probleme komfortabel im Hintergrund gelöst.

Es gibt noch viele Beispiellösungen mit "os" im Internet, da das früher das Mittel der Wahl war. Aber auch die, die diese Lösungen vor einiger Zeit veröffentlicht hatten, würden heute wohl eher pathlib verwenden.
Man muss sich halt umstellen und die neuen Funktionen erstmal lernen.

Hier hätte ich noch eine Lösung, mit pathlib und deiner Sortiermethode:

Code: Alles auswählen

import os
from pathlib import Path

base_path = Path("C:", "Users", "Desktop", "xx", "Datenauswertung_CSV")
csv_files = sorted(base_path.glob("**/*.csv"), key=os.path.getmtime)
Da kommt dann bei mir leider nur folgendes bei raus wenn ich es printe mit:

Code: Alles auswählen

print(base_path)
print(csv_files)
output:

Code: Alles auswählen

C:Users\xx\Desktop\xx\Datenauswertung_CSV
[]
Also mir wird weder der Ordner noch die Datei als Pfad angegeben. Leider komme ich mit dem von dir angegebenen Code somit auf keine Lösung :/
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

Du must diese Zeile wahrscheinlich anpassen.

Code: Alles auswählen

base_path = Path("C:", "Users", "Desktop", "xx", "Datenauswertung_CSV")
Der Pfad ist bestimmt anders bei dir.
Jghurt
User
Beiträge: 32
Registriert: Samstag 8. Mai 2021, 15:18

rogerb hat geschrieben: Freitag 30. Juli 2021, 20:15 Du must diese Zeile wahrscheinlich anpassen.

Code: Alles auswählen

base_path = Path("C:", "Users", "Desktop", "xx", "Datenauswertung_CSV")
Der Pfad ist bestimmt anders bei dir.
Den Pfad hatte ich schon geändert :) Also daran liegt es nicht
Jghurt
User
Beiträge: 32
Registriert: Samstag 8. Mai 2021, 15:18

rogerb hat geschrieben: Freitag 30. Juli 2021, 15:41 @Jghurt,

So bekommst du eine sortierte Liste aller csv-Dateien unter dem Ordner "Messdaten xx.xx.2021".

Code: Alles auswählen

from pathlib import Path

base_path = Path('D:', 'xxxxxx', 'xxxx', 'Sensordaten', 'Messdaten xx.xx.2021')
paths = sorted(base_path.glob("**/*.csv"))
Diese Reihenfolge hängt natürlich von den jeweiligen Pfaden ab. Eventuell musst das noch ein wenig an deine Bedürfnisse anpassen, damit du sicher immer die richtige Datei bekommst.
Hier das selbe.
wenn ich base_path printe, wird nur mein Pfad zum übergeordneten Ordner geprintet.
mit print paths wird nur [] ausgegeben

Also weder die Ausgabe des "aktuellsten Ordners", noch die Ausgabe der obersten CSV Datei
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

Mit

Code: Alles auswählen

sorted(base_path.glob("**/*.csv"))
Bekommst du all csv-Dateien in den Unterverzeichnissen von 'base_bath'. Wie gesagt, du must 'base_path' an deine Ordnerstruktur anpassen und vielleicht eine Ebene höher ansetzen.
Jghurt
User
Beiträge: 32
Registriert: Samstag 8. Mai 2021, 15:18

rogerb hat geschrieben: Samstag 31. Juli 2021, 08:45 Mit

Code: Alles auswählen

sorted(base_path.glob("**/*.csv"))
Bekommst du all csv-Dateien in den Unterverzeichnissen von 'base_bath'. Wie gesagt, du must 'base_path' an deine Ordnerstruktur anpassen und vielleicht eine Ebene höher ansetzen.

Also egal was ich probiere, ich kriege als output mit eurem Vorschlag/Skript immer nur
Jghurt
User
Beiträge: 32
Registriert: Samstag 8. Mai 2021, 15:18

Sirius3 hat geschrieben: Freitag 30. Juli 2021, 16:14 @rogerb: ich befürchte ja, dass die xx eigentlich Zahlen sind, und Du daher nach dem falschen Datum die Ordner sortierst, die "Messdaten 31.07.2021" kommen halt lexikalisch vor den "Messdaten 01.08.2021".

Jetzt kann man entweder eine passende Sortierfunktion für die ungünstige Verzeichnisbenennung finden, oder nach der richtigen csv-Dateibenennung sortieren, bzw. da man nur den neusten Eintrag braucht, aus sorted max machen.

Code: Alles auswählen

from pathlib import Path

base_path = Path('D:/xxxxxx/xxxx/Sensordaten')
csv_path = max(base_path.glob("*/Liste_*.csv"), key=lambda p:p.name)
@Jghurt: os und glob sind veraltet, statt dessen benutzt man pathlib.
Was ist denn die genaue Fehlermeldung?

Also bei deinem Code mit meinem Pfad:

Code: Alles auswählen

import os
from pathlib import Path

base_path = Path("C:", "XX", "XX", "Desktop", "XX", "Datenauswertung_CSV", "Test_Datenauswertung")
csv_path = max(base_path.glob("*/Liste_*.csv"), key=lambda p:p.name)
print(csv_path)
Bekomme ich als Output folgenden Fehler:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:/XX/XX/Desktop/Python/py8.py", line 5, in <module>
    csv_path = max(base_path.glob("*/Liste_*.csv"), key=lambda p:p.name)
ValueError: max() arg is an empty sequence
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Jghurt: Da sind ja laut Deinen Angaben auch keine CSV-Dateien sondern Ordner *in denen* dann die Dateien liegen. Versuchs mal nur mit "Liste_*.csv".

Die Dateizeiten in den Metadaten können übrigens Probleme machen weil die verändert werden können und dann nicht mehr zu dem Datum im Dateinamen passen müssen. Wenn da mal jemand aus versehen oder gar absichtlich eine der Dateien öffnet und wieder speichert, selbst wenn keine Veränderungen vorgenommen wurden, ist die Datei dann plötzlich die ”neueste” was die Zeiten angeht. Oder wenn aus versehen Dateien gelöscht wurden und dann vielleicht von woanders eine Kopie wieder in den Verzeichnisbaum verlegt wird, kann es auch passieren, dass die dann die ”neuesten” sind.

Besser ist es solche Daten im Dateinamen in einem sinnvoll lexikographisch sortierbaren Format zu haben. Was bei den Dateinamen hier wahrscheinlich sogar der Fall ist, aber nicht bei den Verzeichnisnamen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Dann stimmt Deine Verzeichnisstruktur nicht. Wir können ja nur auf dem Aufbauen, was Du uns verraten hast. Das ist dann offensichtlich falsch.
Wie sehen denn Deine Verzeichnise und Dateinamen wirklich aus?
Antworten