mitmario.dev

Umbenennen und verschieben

Python Sandbox 3 Min Lesezeit 5 BeispieleLektion 6 von 8

Fotos vom Handy heißen IMG_20260712_143005.jpg, Scans heißen Scan0001.pdf, und nach dem Urlaub liegen davon ein paar hundert in einem Ordner. Wenn du die von Hand umbenennst, ist der Abend weg, und nach dem dreißigsten Foto vertippst du dich garantiert einmal.

Ein Programm erledigt das in einer Sekunde und vertippt sich nie. Seine Fehler macht es allerdings auch zuverlässig bei allen dreihundert Dateien. Das Umbenennen ist deshalb nur die eine Hälfte. Die andere ist, dabei nichts kaputt zu machen.

Umbenennen

Eine Datei umbenennen
from pathlib import Path

alt = Path("fotos/urlaub.jpg")
neu = alt.parent / "Gardasee 2026.jpg"
alt.rename(neu)

for eintrag in sorted(Path("fotos").iterdir()):
    print(eintrag)

alt.rename(neu) benennt die Datei um. neu ist der vollständige neue Pfad, also Ordner und Name, und deshalb steht alt.parent / … davor. Kürzer geht dasselbe mit alt.with_name("Gardasee 2026.jpg"). Das ist der Pfad mit einem anderen Namen am Ende, im selben Ordner. Am Inhalt der Datei ändert sich nichts, nur ihr Eintrag im Ordner.

Der neue Name allein

Nur der neue Name
from pathlib import Path

alt = Path("fotos/urlaub.jpg")
alt.rename("Gardasee 2026.jpg")

for eintrag in sorted(Path("fotos").iterdir()):
    print(eintrag)
print(Path("Gardasee 2026.jpg").exists())

Hier bekommt rename nur den neuen Namen, ohne Ordner. Ein Name ohne Ordner ist aber ein relativer Pfad, und der gilt vom Arbeitsverzeichnis aus (Lektion 11.4). Die Datei heißt danach also nicht nur anders, sie liegt auch woanders.

Im Ordner fotos steht nur noch der Strand, und Gardasee 2026.jpg liegt ein Stockwerk höher, neben main.py. Bei einem Foto fällt das auf. Bei dreihundert liegen danach dreihundert Fotos zwischen den Programmdateien, und der Fotoordner ist leer.

Verschieben und kopieren

Verschieben und kopieren
import shutil
from pathlib import Path

Path("fotos/2026").mkdir(exist_ok=True)
shutil.move("fotos/urlaub.jpg", "fotos/2026")
Path("sicherung").mkdir(exist_ok=True)
shutil.copy("fotos/strand.jpg", "sicherung")

for ordner in ["fotos", "sicherung"]:
    for eintrag in sorted(Path(ordner).rglob("*")):
        print(eintrag)

Für alles, was über einen neuen Namen hinausgeht, gibt es das Modul shutil (shell utilities, die Werkzeuge, die man sonst im Terminal benutzt). shutil.move(quelle, ziel) verschiebt. Wenn das Ziel ein Ordner ist, landet die Datei darin und behält ihren Namen. Sonst ist das Ziel der neue Pfad. shutil.copy kopiert, das Original bleibt also, wo es war. Beide nehmen Text oder einen Path.

Den Zielordner muss es vorher geben, deshalb steht das mkdir davor. Fehlt er, kommt von shutil.move keine Meldung, und fotos/2026 wird einfach als neuer Name genommen. Danach gibt es eine Datei 2026 ohne Endung, und darin ist das Foto verschwunden.

rename kann übrigens nur innerhalb desselben Laufwerks verschieben. shutil.move schafft es auch auf einen USB-Stick, weil es dort kopiert und danach das Original löscht.

Wenn das Ziel schon da ist

Ein Ziel, das es schon gibt
from pathlib import Path

alt = Path("fotos/IMG_0815.jpg")
neu = alt.with_name("gardasee.jpg")
print("Vorher:", neu.read_text(encoding="utf-8"), end="")
alt.rename(neu)
print("Nachher:", neu.read_text(encoding="utf-8"), end="")

for eintrag in sorted(Path("fotos").iterdir()):
    print(eintrag)

Im Ordner liegt schon ein gardasee.jpg, das gute Foto. Jetzt soll das verwackelte genauso heißen. rename macht das einfach. Danach gibt es nur noch eine Datei, und in der steckt das verwackelte. Das gute ist weg, ohne Meldung und ohne Papierkorb.

So ist es auf Linux und auf dem Mac. Unter Windows endet derselbe Aufruf mit einem FileExistsError. Dasselbe Programm ist also auf dem einen Rechner laut und auf dem anderen still, und still ist hier die schlechtere Variante.

Verlassen sollte man sich auf keins von beiden. Ein Werkzeug, das Dateien umbenennt, fragt vorher mit neu.exists(), ob es das Ziel schon gibt, und lässt die Datei in dem Fall liegen. Mit einer Meldung, damit du weißt, welche.

Erst ein Probelauf

Erst ein Probelauf
from pathlib import Path

WIRKLICH = False

for alt in sorted(Path("fotos").glob("IMG_*.jpg")):
    neu = alt.with_name("Gardasee " + alt.name[4:])
    print(alt.name, "→", neu.name)
    if WIRKLICH:
        alt.rename(neu)

if not WIRKLICH:
    print("Nur ein Probelauf, geändert hat sich nichts.")

Bevor ein Programm Dateien wirklich umbenennt, läuft es besser einmal so, dass es nur zeigt, was es tun würde. Eine Regel, nach der die Hälfte der Bilder plötzlich gleich hieße, fällt in so einer Liste sofort auf. Eine Zeile pro Datei ist schnell gelesen, und ein Fehler darin kostet nichts.

Hier hängt das an einer Variablen in Großbuchstaben, einer Einstellung für das ganze Programm. Steht sie auf False, wird nur ausgegeben. glob("IMG_*.jpg") nimmt dabei nur die Fotos vom Handy, das gute gardasee.jpg bleibt außen vor. Erst wenn die Liste stimmt, setzt man sie auf True und startet noch einmal. In Lektion 11.7 wird daraus ein Schalter beim Start, --wirklich.

Was die Aufgabe will

Im Ordner fotos liegen Fotos vom Handy, in deren Namen Datum und Uhrzeit stecken, in einer Form, die niemand gern liest. Sie sollen so heißen, dass man das Datum auf einen Blick sieht und sie sich trotzdem richtig sortieren. Alles andere im Ordner bleibt, wie es ist, und nichts darf überschrieben werden.

Zum Mitnehmen

Umbenannt wird mit pfad.rename(neu), und neu ist dabei der ganze Pfad, sonst landet die Datei im Arbeitsverzeichnis. Verschieben geht mit shutil.move, kopieren mit shutil.copy. Gibt es das Ziel schon, wird es von rename auf Linux und dem Mac ohne Meldung überschrieben. Deshalb fragt ein gutes Werkzeug vorher exists() und läuft zuerst als Probelauf.

Jetzt du

Basis Konto, kostenlos

Zu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.

Was in dieser Lektion steckt

  • Artikel mit 5 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.

  • Aufgabe, dein Code läuft auf einem Server

    Öffnet sich mit dem Basis Konto.