Was ist, wenn du nicht weißt wie viele Dateien du bekommst? Oder wenn es einfach 10, 20, 50 oder mehr einzelne Dateien sind, die du zusammenführen musst?
Dann ist der Ansatz aus dem letzten Artikel natürlich nicht praktikabel.
Viel schöner wäre es doch, wenn du einfach sagen könntest: “Python! Hier ist der Order, führ mal bitte alle CSV Dateien in dem Ordner zu einer großen zusammen – egal wie viele du findest.“
Genau das erledigen wir jetzt.
Mit os.listdir() kannst du alle Dateien aus einem Verzeichnis auslesen, mit einer for-Schleife drüber iterieren und über csv.reader die Inhalte in einer Variablen speichern. Im Anschluss kannst du alles in einem Rutsch in eine neue Datei schreiben.
Dateien zum Beitrag:
Du weißt nicht, was du mit den Dateien machen sollst? Hier findest du Hilfe.
Um alles aus einem Verzeichnis auszulesen, musst du natürlich auf das Verzeichnis zugreifen können. Dafür bietet Python das Modul ‘os‘. Mit os bekommst du die Möglichkeit mit dem Betriebssystem zu interagieren und verschiedene Dinge zu erledigen. So zum Beispiel auch den Inhalt von einem Ordner auflisten.
Also zuerst einmal das os Modul importieren. Als Nächstes kannst du mit der Funktion listdir() einen Pfad übergeben, dessen Inhalt du auslesen möchtest. Natürlich muss es sich dabei auch um eine ‘dir‘ (Directory / Verzeichnis) handeln.
import os
os.listdir('dateien')
Führst du den Code aus, bekommst du eine Liste mit allen Dateien, die in dem Ordner enthalten sind. Dabei werden die Namen einfach als String, also als Text bereitgestellt. Das hilft natürlich, wenn du zum Beispiel nach bestimmten Dateiendungen filtern möchtest.
Ok. Du hast jetzt also eine Liste mit Dateien. Und jetzt?
Ganz einfach!
Du nimmst dir wieder deinen Code von oben, der Dateien einliest. Nur schreibst du diesmal keinen with open() Block für jede einzelne Datei in deinem Verzeichnis.
Du gehst einfach deine Liste mit Dateien in einer for-Schleife durch und führst das Einlesen für jeden Durchlauf der Schleife aus.
import os
import csv
header = []
daten = []
pfad = 'dateien'
dateien = os.listdir(pfad)
for datei in dateien:
with open(f'{pfad}/{datei}', 'r') as zu_lesen:
reader = csv.reader(zu_lesen, delimiter=',')
header = next(reader)
daten.extend([row for row in reader])
with open('ergebnis.csv', 'w') as ergebnis_datei:
writer = csv.writer(ergebnis_datei, delimiter=',')
writer.writerow(header)
writer.writerows(daten)
Erstmal das Einfache:
Die Kopfzeile wird jetzt in jedem Durchlauf überschrieben.
Das ist natürlich nicht optimal, stört in dem Fall aber nicht, weil die Kopfzeile ja in allen Dateien die Gleiche ist.
Etwas Neues passiert hier aber doch noch:
Du musst den Pfad zusammen bauen.
os.listdir() liefert dir nur den Dateinamen, nicht den Pfad!
with open() wiederum braucht aber einen vollständigen Pfad, um die Datei zu finden.
Das heißt, du musst den Pfad erst wieder mit dem Dateinamen zusammenführen, damit with open() die Datei auch findet.
Am einfachsten ist das über einen f-String.
Ein f-String ist eine einfache Möglichkeit wie du Strings zusammenbauen kannst, während du dabei Variablen benutzt.
Wie du siehst, vorn dran ein ‘f’, dann den String starten und wenn du eine Variable benutzen willst, kommt die einfach in geschweifte Klammern.
Python erkennt dann von alleine, dass der Inhalt der Variable eingefügt werden soll.
Tiefer möchte ich hier nicht auf die f-Strings eingehen. Das würde zu weit vom Thema weg führen.
Dann bleibt eigentlich nur noch eine Anmerkung:
Da die Variable daten direkt mit einer leeren Liste erstellt wurde, kannst du in der Schleife ohne Probleme direkt extend() benutzen. Deine leere Liste wird dann einfach um die neue Liste erweitert und fertig.
Das war’s auch schon!
So einfach kannst du beliebig viele CSV Dateien aus einem Verzeichnis zusammenführen.
Wie kann ich nur CSV Dateien aus einem Verzeichnis zusammenführen?
Oftmals hast du einen Ordner, in dem nicht nur CSV Dateien drin sind. Vielleicht hast du noch Unterordner oder andere Dateitypen in deinem Verzeichnis. Du willst aber natürlich nur die CSV Dateien zusammenführen. Dann kannst du mit einer kleinen Erweiterung ganz einfach nach CSV Dateien filtern.
import os
import csv
header = []
daten = []
pfad = 'dateien'
dateien = os.listdir(pfad)
for datei in dateien:
if datei.endswith('.csv'):
with open(f'{pfad}/{datei}', 'r') as zu_lesen:
reader = csv.reader(zu_lesen, delimiter=',')
header = next(reader)
daten.extend([row for row in reader])
with open('ergebnis.csv', 'w') as ergebnis_datei:
writer = csv.writer(ergebnis_datei, delimiter=',')
writer.writerow(header)
writer.writerows(daten)
In deiner for-Schleife führst du eine Bedingung ein:
Der Dateiname muss mit ‘.csv‘ enden, damit die Datei eingelesen wird. Tut sie das nicht, wird sie einfach übersprungen und es wird mit der nächsten Datei weiter gemacht.
Teilweise passiert es aber auch, dass es nicht ‘.csv‘ ist, sondern vielleicht ‘.Csv‘ oder ‘.CSV‘.
Wiekann man damit umgehen?
Hier hilft dir ein weiteres Python BuiltIn: lower()
Mit lower() wird der ganze String einfach kleingeschrieben. Schon spielt die Groß-/Kleinschreibung keine Rolle mehr und du kannst den Vergleich weiterhin genauso einfach durchführen.
import os
import csv
header = []
daten = []
pfad = 'dateien'
dateien = os.listdir(pfad)
for datei in dateien:
if datei.lower().endswith('.csv'):
with open(f'{pfad}/{datei}', 'r') as zu_lesen:
reader = csv.reader(zu_lesen, delimiter=',')
header = next(reader)
daten.extend([row for row in reader])
with open('ergebnis.csv', 'w') as ergebnis_datei:
writer = csv.writer(ergebnis_datei, delimiter=',')
writer.writerow(header)
writer.writerows(daten)
Hier mal ein Beispiel:
Dein Dateiname ist ‘Datei.Csv’
datei = ‘Datei.Csv’
Wenn du .lower() aufrufst, sieht es so aus:
datei.lower() = ‘datei.csv’
Und nach dem .lower() kommt das .endswith().
endswith() prüft, ob das Ende eines Textes mit dem übergebenen Textstück übereinstimmt.
datei.endswith(‘.csv’) wäre also False, weil ‘Datei.Csv’ nicht mit ‘.csv’ endet, sondern eben mit ‘.Csv’.
Durch das .lower() ist der Vergleich allerdings mit ‘datei.csv’ – also kleingeschrieben. Und somit True, also erfolgreich.
Jetzt spielt es keine Rolle mehr wie viele Dateien du am Ende in dem Verzeichnis hast und ob vielleicht noch ein paar andere Dateitypen mit untergeschmuggelt sind.
Du filterst einfach das raus, was du brauchst, führst es zusammen und schon kannst du wieder was mit deinen Daten anfangen!
Kurse
Code Challenges und YouTube Videos führen nicht immer zum gewünschten Erfolg.
Manchmal ist es besser, gezielt und strukturiert durch ein Thema zu arbeiten.
Schau dich einfach mal bei meinen Kursen um.
Ohne lästiges Blah Blah steigen wir direkt in das Thema ein und behandeln alles, was du brauchst.
Ingo Janssen ist ein Softwareentwickler mit über 10 Jahren Erfahrung in der Leitung seines eigenen Unternehmens.
Er studierte Wirtschaftsinformatik an der TH Deggendorf und hat Softwareentwicklung an der FOM Hochschule in München unterrichtet.
Ingo hat mit einer Vielzahl von Unternehmen zusammengearbeitet, von kleinen und mittelständischen Unternehmen bis hin zu MDAX- und DAX-gelisteten Unternehmen.
Ingo ist leidenschaftlich daran interessiert, sein Wissen und seine Expertise mit anderen zu teilen. Aus diesem Grund betreibt er einen YouTube-Kanal mit Programmier-Tutorials und eine Discord-Community, in der Entwickler miteinander in Kontakt treten und voneinander lernen können.
Sie können Ingo auch auf LinkedIn, Xing und Gulp finden, wo er Updates über seine Arbeit teilt und Einblicke in die Tech-Branche gibt.
YouTube | Discord | LinkedIn | Xing | Gulp Profile