Toptorials Tutorials WeblogoLogobild kleinLogobild kleinToptorials Tutorials Weblogo
  • ALLE THEMEN IM ÜBERBLICK
  • YouTube
  • INFOS
    • SITEMAP
    • ÜBER TOPTORIALS
✕
            No results See all results

            Python Grundkurs 005: Dateien mit einem Präfix umbenennen

            • Startseite
            • Tutorials Windows Automatisierung Python Grundkurs
            • Python Grundkurs 005: Dateien mit einem Präfix umbenennen

            Python Grundkurs 005: Dateien mit einem Präfix umbenennen

            Worum geht es in diesem Teil?

            In diesem fünften Teil des Python-Grundkurses benennen wir Dateien und Ordner automatisch um. Vor den bisherigen Namen wird ein frei wählbares Präfix gesetzt.

            Aus diesen Dateien:

            beleg001.jpg
            notiz.txt
            scan001.pdf

            werden mit einem Datumspräfix zum Beispiel:

            2026-08-12_beleg001.jpg
            2026-08-12_notiz.txt
            2026-08-12_scan001.pdf
            
            
            Vorher

            Vorher

            Nachher

            Nachher

            Alternativ können Datum und Uhrzeit oder ein eigener Text verwendet werden:

            2026-08-12_14-30-25_scan001.pdf
            Ausgaben_scan001.pdf

            Zu diesem Teil gehören drei Varianten:

            00_Einfach
            03_SendTo_Elemente_umbenennen
            04_SendTo_Ordnerinhalt_umbenennen

            Die einfache Variante benennt Dateien im aktuellen Arbeitsordner um.

            Die zweite Variante benennt genau die Dateien und Ordner um, die im Windows-Explorer markiert und über Senden an übergeben wurden. Bei einem ausgewählten Ordner wird nur der Ordner selbst umbenannt, nicht sein Inhalt.

            Die dritte Variante erhält einen oder mehrere Ordner über Senden an und benennt die direkt darin enthaltenen Dateien um. Die übergebenen Ordner selbst und mögliche Unterordner bleiben unverändert.

            Was ist das Ziel?

            Das Ziel ist ein verständliches und möglichst sicheres Python-Werkzeug für wiederkehrende Umbenennungen.

            Dabei gelten wichtige Sicherheitsregeln:

            Zuerst wird nur getestet.
            Im Testmodus werden keine Dateien oder Ordner umbenannt.
            Vorhandene Ziele werden nicht überschrieben.
            Bereits vorhandene Präfixe werden erkannt.
            Leere oder ungültige Präfixe werden abgewiesen.
            Vor dem echten Umbenennen muss JA eingegeben werden.
            Fehler werden kontrolliert abgefangen und gezählt.

            Die Meldungen können wahlweise nur im Fenster angezeigt, als Logdatei gespeichert, in die Zwischenablage kopiert oder über beide zusätzlichen Wege ausgegeben werden.

            Warum ist dieser Teil wichtig?

            In diesem Teil lernen wir mehrere wichtige Python-Grundlagen kennen:

            Module mit import einbinden
            Startargumente mit sys.argv auslesen
            Datum und Uhrzeit mit datetime und strftime() formatieren
            Pfade mit pathlib und Path verarbeiten
            Die besondere Variable __file__ verwenden
            Texte mit casefold() und startswith() vergleichen
            Listen mit append() aufbauen
            Doppelte Werte mit einem set erkennen
            Umbenennungen in Dictionaries vorbereiten
            Listen mit sort() und lambda sortieren
            Dateien und Ordner mit rename() umbenennen
            Fehler mit try und except behandeln
            Protokolle und Statistiken erstellen
            Text in die Windows-Zwischenablage kopieren

            Besonders wichtig ist die Trennung zwischen Planung und tatsächlicher Änderung. Die SendTo-Varianten stellen zunächst Umbenennungspläne zusammen. Erst danach werden die geplanten Vorgänge im Testmodus angezeigt oder im Echtmodus ausgeführt.

            Hinweis zur Kursreihe

            Diese Python-Reihe ist Teil einer größeren Windows-Automatisierungsreihe.

            Viele Aufgaben werden in mehreren Sprachen umgesetzt:

            Batch
            PowerShell 7
            Python

            Dadurch kann man vergleichen, wie dieselbe Aufgabe in unterschiedlichen Sprachen gelöst wird.

            Der Python-Code ist bewusst ausführlich aufgebaut. Einige Abläufe könnten kürzer geschrieben werden, zum Beispiel mit einer sogenannten List Comprehension. Für den Grundkurs bleiben die einzelnen Schleifen, Prüfungen und Arbeitsschritte aber gut sichtbar.

            Downloads zu diesem Teil

            Für diesen Teil gibt es drei Python-Skripte und die dazugehörigen Starter-Batchdateien.

            Dateien für Python Grundkurs Teil 005:


            Download Python Grundkurs: 005_Dateien_mit_Praefix_umbenennen als ZIP-Datei.

            Entpacken nach:

            C:\TOPTORIALS_CODE\020_Python_Grundkurs

            Falls der Ordner noch nicht existiert, lege ihn vorher im Explorer an.

            Nach dem Entpacken entsteht dort:

            C:\TOPTORIALS_CODE\020_Python_Grundkurs\005_Dateien_mit_Praefix_umbenennen

            Darin befinden sich diese drei Unterordner:

            00_Einfach
            03_SendTo_Elemente_umbenennen
            04_SendTo_Ordnerinhalt_umbenennen

            Testumgebung zum Mitmachen

            Für diese Tutorialreihe gibt es zusätzlich eine vorbereitete Testumgebung. Sie enthält Beispieldateien und Ordner, an denen alle drei Varianten gefahrlos ausprobiert werden können.

            Testumgebung für Windows-Automatisierung:

            Download TOPTORIALS_Testdaten_Windows_Automatisierung_V001.zip

            Entpacken nach:

            C:\TOPTORIALS_CODE\1000_TESTBEREICH

            Falls der Ordner C:\TOPTORIALS_CODE\1000_TESTBEREICH noch nicht existiert, lege ihn vorher im Explorer an.

            Für den Python-Grundkurs kann der entpackte Ordner so benannt werden:

            TOPTORIALS_Testdaten_Windows_Automatisierung_Python_V001

            Der vollständige Testpfad für diesen Teil lautet:

            C:\TOPTORIALS_CODE\1000_TESTBEREICH\TOPTORIALS_Testdaten_Windows_Automatisierung_Python_V001\005_Dateien_mit_Praefix_umbenennen

            Die Testdaten können zum Beispiel folgendermaßen aufgebaut sein:

            005_Dateien_mit_Praefix_umbenennen
            ├── 01_Aktueller_Ordner
            │   ├── beleg001.jpg
            │   ├── Einnahmen_scan_alt.pdf
            │   ├── notiz.txt
            │   ├── scan001.pdf
            │   └── scan002.pdf
            ├── 02_SendTo_Elemente
            │   ├── dokument_a.pdf
            │   ├── dokument_b.pdf
            │   ├── Einzelordner_A
            │   ├── Einzelordner_B
            │   └── kassenbon.jpg
            └── 03_SendTo_Ordnerinhalt
                ├── Kasse
                │   ├── bon001.pdf
                │   └── bon002.pdf
                ├── Scans_Ausgaben
                │   ├── quittung.txt
                │   ├── rechnung_buero.pdf
                │   └── tankbeleg.jpg
                ├── Scans_Einnahmen
                │   ├── beleg_maerz.pdf
                │   ├── scan001.pdf
                │   └── scan002.pdf
                └── Sonstige
                    ├── dokument.pdf
                    └── info.txt

            Sicherheitshinweis

            Wichtiger Hinweis:

            Die Skripte werden auf eigene Verantwortung verwendet. Teste sie zuerst in einer separaten Testumgebung und niemals direkt mit wichtigen Originaldateien.

            Solange _test im Namen der Starter-Batchdatei steht, wird das Python-Skript mit dem Startargument --test gestartet. In diesem Modus werden keine Dateien und keine Ordner umbenannt.

            Erst nachdem alle angezeigten Zielnamen geprüft wurden, kann ausschließlich _test aus dem Namen der Starter-Batchdatei entfernt werden. Beim echten Lauf erscheint zusätzlich eine Sicherheitsabfrage. Die Eingaben JA, Ja und ja werden durch upper() akzeptiert.

            Ein gleichnamiges Ziel wird nicht überschrieben. Trotzdem sollte die echte Ausführung zuerst mit Kopien unwichtiger Dateien getestet werden. Besonders bei Datum und Uhrzeit ist zu beachten, dass ein zweiter Lauf mit einem inzwischen veränderten Präfix einen weiteren Präfixbestandteil ergänzen kann.

            Enthaltene Dateien

            Variante 1: Einfach

            00_Einfach
            ├── 005_dateien_mit_praefix_umbenennen.py
            └── 005_dateien_mit_praefix_umbenennen_starter_batch_test.bat

            Variante 2: Ausgewählte SendTo-Elemente umbenennen

            03_SendTo_Elemente_umbenennen
            ├── 005_sendto_elemente_mit_praefix_umbenennen.py
            └── 005_sendto_elemente_mit_praefix_umbenennen_starter_batch_test.bat

            Variante 3: Dateien in ausgewählten SendTo-Ordnern umbenennen

            04_SendTo_Ordnerinhalt_umbenennen
            ├── 005_sendto_ordnerinhalt_mit_praefix_umbenennen.py
            └── 005_sendto_ordnerinhalt_mit_praefix_umbenennen_starter_batch_test.bat

            Präfix einstellen

            In allen drei Python-Dateien stehen dieselben drei vorbereiteten Präfixvarianten. Es darf immer nur eine Zeile aktiv sein.

            Variante 1: Aktuelles Datum

            praefix = datetime.now().strftime("%Y-%m-%d_")

            Ein möglicher neuer Name lautet:

            2026-08-12_rechnung.pdf

            Variante 2: Datum und Uhrzeit

            # praefix = datetime.now().strftime("%Y-%m-%d_%H-%M-%S_")

            Zum Aktivieren wird das Kommentarzeichen entfernt und die bisher aktive Variante auskommentiert:

            # praefix = datetime.now().strftime("%Y-%m-%d_")
            praefix = datetime.now().strftime("%Y-%m-%d_%H-%M-%S_")

            Ein möglicher neuer Name lautet:

            2026-08-12_14-30-25_rechnung.pdf

            Variante 3: Eigener Text

            # praefix = "Ausgaben_"

            Nach dem Aktivieren entsteht zum Beispiel:

            Ausgaben_rechnung.pdf

            Zeichen wie \, /, :, *, ?, ", <, > und | sind in Windows-Dateinamen nicht zulässig. Das Skript prüft das eingestellte Präfix vor der Verarbeitung.

            Datums- und Zeitformatierung mit strftime()

            Die Methode strftime() formatiert ein Datum oder eine Uhrzeit als Text. Die Platzhalter beginnen in Python mit einem Prozentzeichen:

            %Y    Jahr mit vier Stellen, zum Beispiel 2026
            %y    Jahr mit zwei Stellen, zum Beispiel 26
            %m    Monat mit zwei Stellen, zum Beispiel 08
            %d    Tag mit zwei Stellen, zum Beispiel 05
            %H    Stunde im 24-Stunden-Format
            %I    Stunde im 12-Stunden-Format
            %M    Minute mit zwei Stellen
            %S    Sekunde mit zwei Stellen

            Wichtig ist die Groß- und Kleinschreibung. %m steht für den Monat, %M dagegen für die Minute. Doppelpunkte dürfen in Windows-Dateinamen nicht verwendet werden. Deshalb trennt das Skript Stunden, Minuten und Sekunden mit Bindestrichen.

            Zusätzliche Ausgabe einstellen

            Auch bei der Ausgabe darf immer nur eine der vier vorbereiteten Varianten aktiv sein:

            Nur Bildschirmausgabe
            Logdatei erstellen
            Nur in die Zwischenablage kopieren
            Logdatei erstellen und in die Zwischenablage kopieren

            Die Einstellung erfolgt über zwei Wahrheitswerte:

            logdatei_erstellen = False
            zwischenablage_verwenden = False

            True schaltet eine Funktion ein, False schaltet sie aus.

            Variante 1: Dateien im aktuellen Ordner umbenennen

            Die einfache Variante wird gemeinsam mit ihrer Starter-Batchdatei in den Ordner kopiert, dessen Dateien umbenannt werden sollen.

            Für die Testumgebung ist das:

            C:\TOPTORIALS_CODE\1000_TESTBEREICH\TOPTORIALS_Testdaten_Windows_Automatisierung_Python_V001\005_Dateien_mit_Praefix_umbenennen\01_Aktueller_Ordner

            Danach wird diese Datei per Doppelklick gestartet:

            005_dateien_mit_praefix_umbenennen_starter_batch_test.bat

            Im Testmodus erscheint zum Beispiel:

            WÜRDE UMBENENNEN: "beleg001.jpg" zu "2026-08-12_beleg001.jpg"
            WÜRDE UMBENENNEN: "scan001.pdf" zu "2026-08-12_scan001.pdf"

            Die Python-Datei, die Starter-Batchdatei und bereits vorhandene Protokolldateien werden geschützt und übersprungen.

            Wenn alles richtig aussieht, wird nur _test aus dem Namen der Starter-Batchdatei entfernt:

            005_dateien_mit_praefix_umbenennen_starter_batch.bat

            Die Python-Datei selbst wird nicht umbenannt.

            Der komplette Code der einfachen Python-Datei

            Die Datei heißt:

            005_dateien_mit_praefix_umbenennen.py
            # ============================================================
            # TOPTORIALS OFFICE - Python Grundkurs
            # Script: 005_dateien_mit_praefix_umbenennen.py
            # Beschreibung: Benennt Dateien im Skriptordner mit einem Präfix um.
            # Autor: Chris
            # YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
            # Webseite: https://www.toptorials.com
            # Version: 1.0
            # Stand: 2026-08-12
            # ============================================================
            
            from datetime import datetime
            from pathlib import Path
            import subprocess
            import sys
            
            
            print()
            print("Dateien werden mit einem Präfix umbenannt...")
            print()
            
            basis_ordner = Path.cwd()
            testmodus = "--test" in sys.argv
            
            
            # ------------------------------------------------------------
            # Gewünschte Präfixvariante auswählen
            # Wichtig: Immer nur EINE der folgenden Varianten aktiv lassen.
            # ------------------------------------------------------------
            
            # Variante 1: Aktuelles Datum
            praefix = datetime.now().strftime("%Y-%m-%d_")
            
            # Variante 2: Aktuelles Datum und aktuelle Uhrzeit
            # praefix = datetime.now().strftime("%Y-%m-%d_%H-%M-%S_")
            
            # Variante 3: Eigener Text
            # praefix = "Ausgaben_"
            
            
            # ------------------------------------------------------------
            # Welche zusätzliche Ausgabe soll erstellt werden?
            # Wichtig: Immer nur EINE der folgenden Varianten aktiv lassen.
            # ------------------------------------------------------------
            
            # Variante 1: Nur Bildschirmausgabe
            logdatei_erstellen = False
            zwischenablage_verwenden = False
            
            # Variante 2: Logdatei erstellen
            # logdatei_erstellen = True
            # zwischenablage_verwenden = False
            
            # Variante 3: Nur in die Zwischenablage kopieren
            # logdatei_erstellen = False
            # zwischenablage_verwenden = True
            
            # Variante 4: Logdatei erstellen und in die Zwischenablage kopieren
            # logdatei_erstellen = True
            # zwischenablage_verwenden = True
            
            
            # ------------------------------------------------------------
            # Präfix prüfen
            # ------------------------------------------------------------
            
            ungueltige_zeichen = '<>:"/\\|?*'
            
            if not praefix.strip() or any(zeichen in praefix for zeichen in ungueltige_zeichen):
                print("FEHLER: Das eingestellte Präfix ist leer oder enthält ungültige Zeichen.")
                print()
                input("Drücke Enter zum Beenden")
                sys.exit()
            
            if testmodus:
                modus_text = "TESTMODUS"
            else:
                modus_text = "ECHTMODUS"
            
            anzahl_umbenannt = 0
            anzahl_uebersprungen = 0
            anzahl_fehler = 0
            protokoll = []
            
            protokoll.append("Dateien werden mit einem Präfix umbenannt.")
            protokoll.append(f"Modus: {modus_text}")
            protokoll.append(f"Präfix: {praefix}")
            protokoll.append(f"Verarbeiteter Ordner: {basis_ordner}")
            protokoll.append("")
            
            print(f"Modus: {modus_text}")
            print(f"Präfix: {praefix}")
            print(f"Verarbeiteter Ordner: {basis_ordner}")
            print()
            
            
            # ------------------------------------------------------------
            # Sicherheitsabfrage bei der echten Ausführung
            # ------------------------------------------------------------
            
            if not testmodus:
                print("ACHTUNG: Dieses Skript wird Dateien wirklich umbenennen.")
                print()
            
                antwort = input("Zum Fortfahren JA eingeben: ")
            
                if antwort.upper() != "JA":
                    print()
                    print("Abgebrochen.")
                    print()
                    input("Drücke Enter zum Beenden")
                    sys.exit()
            
            
            # ------------------------------------------------------------
            # Dateien erfassen
            # Python-Skript, Starter-Batchdatei und alte Protokolle
            # werden geschützt und nicht umbenannt.
            # ------------------------------------------------------------
            
            dateien = []
            
            try:
                for pfad in basis_ordner.iterdir():
                    if pfad.is_file():
                        dateien.append(pfad)
            except OSError as fehler:
                print(f"FEHLER: Der Ordner konnte nicht gelesen werden. Grund: {fehler}")
                print()
                input("Drücke Enter zum Beenden")
                sys.exit()
            
            skript_pfad = Path(__file__).resolve()
            
            for datei in dateien:
                name_klein = datei.name.lower()
                ist_geschuetzt = (
                    datei.resolve() == skript_pfad
                    or (
                        name_klein.startswith(
                            "005_dateien_mit_praefix_umbenennen_starter_batch"
                        )
                        and name_klein.endswith(".bat")
                    )
                    or (
                        name_klein.startswith("umbenennprotokoll_")
                        and name_klein.endswith(".log")
                    )
                )
            
                if ist_geschuetzt:
                    meldung = (
                        f'ÜBERSPRUNGEN: "{datei.name}" - '
                        "Skript- oder Protokolldatei ist geschützt"
                    )
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_uebersprungen += 1
                    continue
            
                if datei.name.casefold().startswith(praefix.casefold()):
                    meldung = (
                        f'ÜBERSPRUNGEN: "{datei.name}" - '
                        "Präfix ist bereits am Anfang enthalten"
                    )
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_uebersprungen += 1
                    continue
            
                neuer_name = praefix + datei.name
                ziel_pfad = basis_ordner / neuer_name
            
                if ziel_pfad.exists():
                    meldung = (
                        f'ÜBERSPRUNGEN: "{datei.name}" - '
                        f'Ziel existiert bereits: "{ziel_pfad}"'
                    )
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_uebersprungen += 1
                    continue
            
                if testmodus:
                    meldung = f'WÜRDE UMBENENNEN: "{datei.name}" zu "{neuer_name}"'
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_umbenannt += 1
                    continue
            
                try:
                    datei.rename(ziel_pfad)
                    meldung = f'UMBENANNT: "{datei.name}" zu "{neuer_name}"'
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_umbenannt += 1
                except OSError as fehler:
                    meldung = (
                        f'FEHLER: "{datei.name}" konnte nicht umbenannt werden. '
                        f"Grund: {fehler}"
                    )
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_fehler += 1
            
            
            # ------------------------------------------------------------
            # Zusammenfassung
            # ------------------------------------------------------------
            
            protokoll.append("")
            protokoll.append("Fertig.")
            
            print()
            print("Fertig.")
            print()
            
            if testmodus:
                meldung_1 = f"Anzahl Dateien, die umbenannt würden: {anzahl_umbenannt}"
                meldung_2 = f"Anzahl übersprungen: {anzahl_uebersprungen}"
                meldung_3 = f"Anzahl Fehler: {anzahl_fehler}"
            
                print(meldung_1)
                print(meldung_2)
                print(meldung_3)
                print()
                print("Es wurden keine Dateien umbenannt.")
                print("Wenn alles richtig aussieht, entferne _test aus dem Namen der Starter-Batchdatei.")
            
                protokoll.append(meldung_1)
                protokoll.append(meldung_2)
                protokoll.append(meldung_3)
                protokoll.append("Es wurden keine Dateien umbenannt.")
            else:
                meldung_1 = f"Anzahl umbenannt: {anzahl_umbenannt}"
                meldung_2 = f"Anzahl übersprungen: {anzahl_uebersprungen}"
                meldung_3 = f"Anzahl Fehler: {anzahl_fehler}"
            
                print(meldung_1)
                print(meldung_2)
                print(meldung_3)
            
                protokoll.append(meldung_1)
                protokoll.append(meldung_2)
                protokoll.append(meldung_3)
            
            
            # ------------------------------------------------------------
            # Optionale Ausgabe als Logdatei und in die Zwischenablage
            # ------------------------------------------------------------
            
            protokoll_text = "\n".join(protokoll)
            zeitstempel = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
            logdatei = basis_ordner / f"umbenennprotokoll_{zeitstempel}.log"
            
            if logdatei_erstellen:
                try:
                    logdatei.write_text(protokoll_text, encoding="utf-8")
                    print()
                    print("Das Protokoll wurde erstellt:")
                    print(logdatei)
                except OSError as fehler:
                    print()
                    print(f"FEHLER: Das Protokoll konnte nicht erstellt werden. Grund: {fehler}")
            
            if zwischenablage_verwenden:
                try:
                    subprocess.run(
                        "clip",
                        input=protokoll_text,
                        text=True,
                        encoding="utf-8",
                        check=True,
                    )
                    print()
                    print("Das Protokoll wurde zusätzlich in die Zwischenablage kopiert.")
                except (OSError, subprocess.CalledProcessError) as fehler:
                    print()
                    print(f"FEHLER: Das Protokoll konnte nicht kopiert werden. Grund: {fehler}")
            
            print()
            input("Drücke Enter zum Beenden")

            Code der einfachen Python-Datei erklärt

            Benötigte Module importieren

            from datetime import datetime
            from pathlib import Path
            import subprocess
            import sys

            datetime liefert Datum und Uhrzeit. Path verarbeitet Datei- und Ordnerpfade. subprocess startet das Windows-Programm clip. sys stellt unter anderem Startargumente und sys.exit() bereit.

            Aktuellen Arbeitsordner und Testmodus ermitteln

            basis_ordner = Path.cwd()
            testmodus = "--test" in sys.argv

            Path.cwd() liefert den aktuellen Arbeitsordner. Die Starter-Batchdatei wechselt vorher genau in ihren eigenen Ordner. Dadurch bearbeitet die einfache Variante den Ordner, in dem die beiden Kursdateien liegen.

            Präfix auf ungültige Zeichen prüfen

            ungueltige_zeichen = '<>:"/\\|?*'
            
            if not praefix.strip() or any(zeichen in praefix for zeichen in ungueltige_zeichen):

            strip() entfernt für die Prüfung Leerzeichen am Anfang und Ende. Ist danach nichts mehr übrig, ist das Präfix leer. any() liefert True, sobald mindestens eines der ungültigen Zeichen im Präfix gefunden wird.

            Pfad des laufenden Skripts mit __file__ ermitteln

            skript_pfad = Path(__file__).resolve()

            __file__ ist eine besondere, von Python bereitgestellte Variable. Sie enthält den Pfad der aktuell ausgeführten Python-Datei. Path() erstellt daraus ein Pfadobjekt und resolve() ermittelt den vollständigen absoluten Pfad.

            Namen mit zwei Unterstrichen am Anfang und Ende werden häufig Dunder-Namen genannt. Dunder steht für double underscore. Weitere bekannte Beispiele sind __name__, __main__, __doc__ und __init__.

            Geschützte Dateien erkennen

            name_klein = datei.name.lower()
            ist_geschuetzt = (
                datei.resolve() == skript_pfad
                or (...)
                or (...)
            )

            Die Python-Datei wird über ihren vollständigen Pfad erkannt. Die Starter-Batchdatei und mögliche Protokolle werden anhand ihres Namens und ihrer Dateiendung geschützt. Durch or genügt es, wenn eine dieser Bedingungen zutrifft.

            Vorhandenes Präfix unabhängig von Groß- und Kleinschreibung erkennen

            if datei.name.casefold().startswith(praefix.casefold()):

            casefold() vereinheitlicht einen Text für einen Vergleich ohne Beachtung der Groß- und Kleinschreibung. Es ist für solche Vergleiche noch etwas gründlicher als lower(). Danach prüft startswith(), ob der Dateiname mit dem gewünschten Präfix beginnt.

            Ausführlicher könnte derselbe Ablauf so geschrieben werden:

            dateiname_fuer_vergleich = datei.name.casefold()
            praefix_fuer_vergleich = praefix.casefold()
            
            if dateiname_fuer_vergleich.startswith(praefix_fuer_vergleich):

            Neuen Namen und Zielpfad bilden

            neuer_name = praefix + datei.name
            ziel_pfad = basis_ordner / neuer_name

            Der neue Name besteht aus dem Präfix und dem bisherigen Namen. Der Schrägstrich zwischen zwei Path-Objekten setzt Pfadbestandteile zusammen. Er erzeugt hier keinen Text mit einem Schrägstrich, sondern einen vollständigen Pfad für das jeweilige Betriebssystem.

            Datei mit rename() umbenennen

            try:
                datei.rename(ziel_pfad)
            except OSError as fehler:

            rename() führt die Umbenennung aus. Tritt dabei ein typischer Datei- oder Betriebssystemfehler auf, fängt except OSError ihn ab. Der Fehler kann ausgegeben und gezählt werden, während das Skript mit der nächsten Datei fortfährt.

            Der komplette Code der einfachen Starter-Batchdatei

            @echo off
            REM ============================================================
            REM TOPTORIALS OFFICE - Python Grundkurs
            REM Script: 005_dateien_mit_praefix_umbenennen_starter_batch_test.bat
            REM Beschreibung: Startet das Python-Skript im Testmodus.
            REM Autor: Chris
            REM YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
            REM Webseite: https://www.toptorials.com
            REM Version: 1.0
            REM Stand: 2026-08-12
            REM
            REM Hinweis:
            REM Solange _test im Dateinamen steht, wird --test uebergeben.
            REM Fuer die echte Ausfuehrung _test aus dem Dateinamen entfernen.
            REM ============================================================
            
            chcp 65001 >nul
            cd /d "%~dp0"
            
            echo %~n0 | find /i "_test" >nul
            
            if not errorlevel 1 (
                py "005_dateien_mit_praefix_umbenennen.py" --test
                REM Alternative, falls py nicht funktioniert:
                REM python "005_dateien_mit_praefix_umbenennen.py" --test
            ) else (
                py "005_dateien_mit_praefix_umbenennen.py"
                REM Alternative, falls py nicht funktioniert:
                REM python "005_dateien_mit_praefix_umbenennen.py"
            )

            Code der einfachen Starter-Batchdatei erklärt

            chcp 65001 >nul
            cd /d "%~dp0"

            chcp 65001 aktiviert UTF-8 für Umlaute und andere Zeichen. %~dp0 enthält Laufwerk und Ordner der Starter-Batchdatei. cd /d wechselt dorthin und kann dabei auch das Laufwerk wechseln.

            echo %~n0 | find /i "_test" >nul

            %~n0 liefert den Namen der laufenden Batchdatei ohne Dateiendung. find /i sucht darin ohne Beachtung der Groß- und Kleinschreibung nach _test.

            py "005_dateien_mit_praefix_umbenennen.py" --test

            Solange _test im Batchdateinamen steht, wird --test an Python übergeben. Nach dem Entfernen von _test startet der andere Zweig das Skript ohne Testargument.

            Variante 2: Ausgewählte Dateien und Ordner über SendTo umbenennen

            Diese Variante benennt die im Explorer ausgewählten Elemente selbst um. Ausgewählte Dateien erhalten ein Präfix vor ihrem Dateinamen. Ausgewählte Ordner erhalten ein Präfix vor ihrem Ordnernamen. Inhalte ausgewählter Ordner werden dabei nicht automatisch bearbeitet.

            Die Starter-Batchdatei wird als Verknüpfung in den Windows-Ordner Senden an aufgenommen. Danach können ein oder mehrere Elemente markiert und über das Kontextmenü an das Skript übergeben werden.

            Der komplette Code der SendTo-Elemente-Python-Datei

            # ============================================================
            # TOPTORIALS OFFICE - Python Grundkurs
            # Script: 005_sendto_elemente_mit_praefix_umbenennen.py
            # Beschreibung: Benennt über SendTo übergebene Dateien und Ordner mit einem Präfix um.
            # Autor: Chris
            # YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
            # Webseite: https://www.toptorials.com
            # Version: 1.0
            # Stand: 2026-08-12
            # ============================================================
            
            from datetime import datetime
            from pathlib import Path
            import subprocess
            import sys
            
            
            print()
            
            argumente = sys.argv[1:]
            testmodus = "--test" in argumente
            
            
            # ------------------------------------------------------------
            # Das Argument "--test" aus den übrigen Argumenten herausfiltern
            # ------------------------------------------------------------
            
            # Ausführlich geschrieben ist dieser Ablauf leichter verständlich.
            
            argumente_ohne_test = []
            
            for argument in argumente:
                if argument != "--test":
                    argumente_ohne_test.append(argument)
            
            argumente = argumente_ohne_test
            
            
            # Die entsprechende Kurzschreibweise nennt man List Comprehension.
            
            # argumente = [argument for argument in argumente if argument != "--test"]
            
            
            # ------------------------------------------------------------
            # Prüfen, ob mindestens ein Element übergeben wurde
            # ------------------------------------------------------------
            
            if not argumente:
                print("Bitte sende mindestens eine Datei oder einen Ordner an dieses Skript.")
                print()
                print("Du kannst Dateien oder Ordner im Explorer markieren,")
                print("rechts anklicken und anschließend 'Senden an' verwenden.")
                print()
                input("Drücke Enter zum Beenden")
                sys.exit()
            
            
            # ------------------------------------------------------------
            # Gewünschte Präfixvariante auswählen
            # Wichtig: Immer nur EINE der folgenden Varianten aktiv lassen.
            # ------------------------------------------------------------
            
            # Variante 1: Aktuelles Datum
            praefix = datetime.now().strftime("%Y-%m-%d_")
            
            # Variante 2: Aktuelles Datum und aktuelle Uhrzeit
            # praefix = datetime.now().strftime("%Y-%m-%d_%H-%M-%S_")
            
            # Variante 3: Eigener Text
            # praefix = "Ausgaben_"
            
            
            # ------------------------------------------------------------
            # Welche zusätzliche Ausgabe soll erstellt werden?
            # Wichtig: Immer nur EINE der folgenden Varianten aktiv lassen.
            # ------------------------------------------------------------
            
            # Variante 1: Nur Bildschirmausgabe
            logdatei_erstellen = False
            zwischenablage_verwenden = False
            
            # Variante 2: Logdatei erstellen
            # logdatei_erstellen = True
            # zwischenablage_verwenden = False
            
            # Variante 3: Nur in die Zwischenablage kopieren
            # logdatei_erstellen = False
            # zwischenablage_verwenden = True
            
            # Variante 4: Logdatei erstellen und in die Zwischenablage kopieren
            # logdatei_erstellen = True
            # zwischenablage_verwenden = True
            
            
            # ------------------------------------------------------------
            # Präfix und Modus vorbereiten
            # ------------------------------------------------------------
            
            ungueltige_zeichen = '<>:"/\\|?*'
            
            if not praefix.strip() or any(zeichen in praefix for zeichen in ungueltige_zeichen):
                print("FEHLER: Das eingestellte Präfix ist leer oder enthält ungültige Zeichen.")
                print()
                input("Drücke Enter zum Beenden")
                sys.exit()
            
            if testmodus:
                modus_text = "TESTMODUS"
            else:
                modus_text = "ECHTMODUS"
            
            anzahl_umbenannt = 0
            anzahl_uebersprungen = 0
            anzahl_fehler = 0
            protokoll = []
            plaene = []
            
            protokoll.append("Übergebene Dateien und Ordner werden mit einem Präfix umbenannt.")
            protokoll.append(f"Modus: {modus_text}")
            protokoll.append(f"Präfix: {praefix}")
            protokoll.append("")
            
            print("Dateien und Ordner werden mit einem Präfix umbenannt...")
            print()
            print(f"Modus: {modus_text}")
            print(f"Präfix: {praefix}")
            print()
            
            
            # ------------------------------------------------------------
            # Umbenennungen vorbereiten und prüfen
            # Doppelt übergebene Pfade werden nur einmal verarbeitet.
            # ------------------------------------------------------------
            
            eindeutige_argumente = []
            bereits_vorhanden = set()
            
            for element_pfad in argumente:
                vergleichs_pfad = str(Path(element_pfad).absolute()).casefold()
            
                if vergleichs_pfad not in bereits_vorhanden:
                    bereits_vorhanden.add(vergleichs_pfad)
                    eindeutige_argumente.append(element_pfad)
            
            for element_pfad in eindeutige_argumente:
                element = Path(element_pfad)
            
                if not element.exists():
                    meldung = f'ÜBERSPRUNGEN: Pfad wurde nicht gefunden: "{element_pfad}"'
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_uebersprungen += 1
                    continue
            
                try:
                    element = element.resolve()
                except OSError as fehler:
                    meldung = (
                        f'FEHLER: Element konnte nicht gelesen werden: "{element_pfad}". '
                        f"Grund: {fehler}"
                    )
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_fehler += 1
                    continue
            
                if element.parent == element:
                    meldung = (
                        "ÜBERSPRUNGEN: Eine Laufwerkswurzel kann nicht umbenannt werden: "
                        f'"{element}"'
                    )
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_uebersprungen += 1
                    continue
            
                if element.name.casefold().startswith(praefix.casefold()):
                    meldung = (
                        f'ÜBERSPRUNGEN: "{element}" - '
                        "Präfix ist bereits am Anfang enthalten"
                    )
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_uebersprungen += 1
                    continue
            
                neuer_name = praefix + element.name
                ziel_pfad = element.parent / neuer_name
            
                if ziel_pfad.exists():
                    meldung = (
                        f'ÜBERSPRUNGEN: "{element}" - '
                        f'Ziel existiert bereits: "{ziel_pfad}"'
                    )
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_uebersprungen += 1
                    continue
            
                plaene.append(
                    {
                        "quelle": element,
                        "alter_name": element.name,
                        "neuer_name": neuer_name,
                        "ziel": ziel_pfad,
                    }
                )
            
            
            # ------------------------------------------------------------
            # Sicherheitsabfrage bei der echten Ausführung
            # ------------------------------------------------------------
            
            if not testmodus and plaene:
                print("ACHTUNG: Dieses Skript wird die übergebenen Dateien und Ordner wirklich umbenennen.")
                print()
            
                antwort = input("Zum Fortfahren JA eingeben: ")
            
                if antwort.upper() != "JA":
                    print()
                    print("Abgebrochen.")
                    print()
                    input("Drücke Enter zum Beenden")
                    sys.exit()
            
                print()
            
            
            # ------------------------------------------------------------
            # Dateien und Ordner umbenennen
            # Längere Pfade werden zuerst verarbeitet. Dadurch können auch
            # verschachtelt übergebene Elemente kontrollierter behandelt werden.
            # ------------------------------------------------------------
            
            plaene.sort(key=lambda plan: len(str(plan["quelle"])), reverse=True)
            
            for plan in plaene:
                if testmodus:
                    meldung = (
                        f'WÜRDE UMBENENNEN: "{plan["quelle"]}" '
                        f'zu "{plan["ziel"]}"'
                    )
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_umbenannt += 1
                    continue
            
                try:
                    plan["quelle"].rename(plan["ziel"])
                    meldung = f'UMBENANNT: "{plan["quelle"]}" zu "{plan["ziel"]}"'
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_umbenannt += 1
                except OSError as fehler:
                    meldung = (
                        f'FEHLER: "{plan["quelle"]}" konnte nicht umbenannt werden. '
                        f"Grund: {fehler}"
                    )
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_fehler += 1
            
            
            # ------------------------------------------------------------
            # Zusammenfassung
            # ------------------------------------------------------------
            
            protokoll.append("")
            protokoll.append("Fertig.")
            
            print()
            print("Fertig.")
            print()
            
            if testmodus:
                meldung_1 = f"Anzahl Elemente, die umbenannt würden: {anzahl_umbenannt}"
                meldung_2 = f"Anzahl übersprungen: {anzahl_uebersprungen}"
                meldung_3 = f"Anzahl Fehler: {anzahl_fehler}"
            
                print(meldung_1)
                print(meldung_2)
                print(meldung_3)
                print()
                print("Es wurden keine Dateien oder Ordner umbenannt.")
                print("Wenn alles richtig aussieht, entferne _test aus dem Namen der Starter-Batchdatei.")
            
                protokoll.append(meldung_1)
                protokoll.append(meldung_2)
                protokoll.append(meldung_3)
                protokoll.append("Es wurden keine Dateien oder Ordner umbenannt.")
            else:
                meldung_1 = f"Anzahl umbenannt: {anzahl_umbenannt}"
                meldung_2 = f"Anzahl übersprungen: {anzahl_uebersprungen}"
                meldung_3 = f"Anzahl Fehler: {anzahl_fehler}"
            
                print(meldung_1)
                print(meldung_2)
                print(meldung_3)
            
                protokoll.append(meldung_1)
                protokoll.append(meldung_2)
                protokoll.append(meldung_3)
            
            
            # ------------------------------------------------------------
            # Optionale Ausgabe als Logdatei und in die Zwischenablage
            # ------------------------------------------------------------
            
            protokoll_text = "\n".join(protokoll)
            zeitstempel = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
            skript_ordner = Path(__file__).resolve().parent
            logdatei = skript_ordner / f"umbenennprotokoll_elemente_{zeitstempel}.log"
            
            if logdatei_erstellen:
                try:
                    logdatei.write_text(protokoll_text, encoding="utf-8")
                    print()
                    print("Das Protokoll wurde erstellt:")
                    print(logdatei)
                except OSError as fehler:
                    print()
                    print(f"FEHLER: Das Protokoll konnte nicht erstellt werden. Grund: {fehler}")
            
            if zwischenablage_verwenden:
                try:
                    subprocess.run(
                        "clip",
                        input=protokoll_text,
                        text=True,
                        encoding="utf-8",
                        check=True,
                    )
                    print()
                    print("Das Protokoll wurde zusätzlich in die Zwischenablage kopiert.")
                except (OSError, subprocess.CalledProcessError) as fehler:
                    print()
                    print(f"FEHLER: Das Protokoll konnte nicht kopiert werden. Grund: {fehler}")
            
            print()
            input("Drücke Enter zum Beenden")

            Code der SendTo-Elemente-Datei erklärt

            Startargumente erfassen

            argumente = sys.argv[1:]
            testmodus = "--test" in argumente

            sys.argv ist eine Liste aller Startargumente. Der Eintrag mit dem Index 0 beschreibt das gestartete Python-Skript selbst. Der Ausschnitt [1:] übernimmt deshalb alle Einträge ab Index 1.

            Das Testargument ausführlich herausfiltern

            argumente_ohne_test = []
            
            for argument in argumente:
                if argument != "--test":
                    argumente_ohne_test.append(argument)
            
            argumente = argumente_ohne_test

            Die Schleife erstellt eine neue Liste. Nur Einträge, die nicht --test entsprechen, werden mit append() übernommen. Anschließend ersetzt die gefilterte Liste die bisherige Argumentliste. Dadurch versucht das Skript später nicht, --test wie einen Datei- oder Ordnerpfad zu verarbeiten.

            Die entsprechende Kurzschreibweise heißt List Comprehension:

            argumente = [argument for argument in argumente if argument != "--test"]

            Sie führt denselben Ablauf in einer Zeile aus. Im Grundkurs verwenden wir die ausführliche Form, weil Schleife, Bedingung und append() einzeln zu erkennen sind.

            Doppelte Übergaben mit einem set erkennen

            eindeutige_argumente = []
            bereits_vorhanden = set()

            Ein set ist eine Menge, in der jeder Wert nur einmal vorkommen kann. set() erzeugt hier ein leeres Set. Leere geschweifte Klammern {} würden dagegen ein leeres Dictionary erzeugen.

            Ein gefülltes Set kann so geschrieben werden:

            dateiendungen = {".jpg", ".png", ".pdf"}

            Die alleinige Schreibweise set[] ist nicht gültig. Eckige Klammern werden bei set zum Beispiel in einer Typangabe verwendet:

            bereits_vorhanden: set[str] = set()

            Diese Typangabe ist für das Skript nicht erforderlich.

            if vergleichs_pfad not in bereits_vorhanden:
                bereits_vorhanden.add(vergleichs_pfad)
                eindeutige_argumente.append(element_pfad)

            not in prüft, ob der Vergleichspfad noch nicht gespeichert wurde. add() fügt ihn dem Set hinzu. Die ursprüngliche Pfadangabe wird zusätzlich in einer normalen Liste gespeichert, damit die Übergabereihenfolge erhalten bleibt.

            Pfad für einen Vergleich vorbereiten

            vergleichs_pfad = str(Path(element_pfad).absolute()).casefold()

            Path() erstellt ein Pfadobjekt, absolute() einen absoluten Pfad und str() daraus wieder Text. casefold() verhindert, dass derselbe Windows-Pfad nur wegen unterschiedlicher Groß- und Kleinschreibung mehrfach verarbeitet wird.

            Eine Laufwerkswurzel erkennen

            if element.parent == element:

            Bei einer Laufwerkswurzel wie C:\ ist der Elternpfad wieder die Laufwerkswurzel selbst. Die Prüfung verhindert, dass das Skript versucht, eine Laufwerkswurzel umzubenennen.

            Umbenennungen in Dictionaries planen

            plaene.append(
                {
                    "quelle": element,
                    "alter_name": element.name,
                    "neuer_name": neuer_name,
                    "ziel": ziel_pfad,
                }
            )

            Für jede geplante Umbenennung wird ein Dictionary erstellt. Darin stehen Quelle, alter Name, neuer Name und Zielpfad unter klar benannten Schlüsseln. Das Dictionary wird mit append() der Liste plaene hinzugefügt.

            Längere Pfade zuerst sortieren

            plaene.sort(key=lambda plan: len(str(plan["quelle"])), reverse=True)

            sort() sortiert die Liste. Der Parameter key legt fest, welcher Wert für den Vergleich benutzt wird. Die anonyme Funktion lambda ermittelt für jeden Plan die Länge des Quellpfades. reverse=True dreht die Sortierung um, sodass längere Pfade zuerst kommen.

            Dadurch kann zuerst eine ausgewählte Datei in einem Ordner und anschließend der ebenfalls ausgewählte Ordner selbst umbenannt werden. Würde zuerst der Ordner umbenannt, wäre der zuvor geplante alte Dateipfad nicht mehr gültig.

            Der komplette Code der SendTo-Elemente-Starter-Batchdatei

            @echo off
            REM ============================================================
            REM TOPTORIALS OFFICE - Python Grundkurs
            REM Script: 005_sendto_elemente_mit_praefix_umbenennen_starter_batch_test.bat
            REM Beschreibung: Startet die SendTo-Variante für Dateien und Ordner.
            REM Autor: Chris
            REM YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
            REM Webseite: https://www.toptorials.com
            REM Version: 1.0
            REM Stand: 2026-08-12
            REM
            REM Hinweis:
            REM Solange _test im Dateinamen steht, wird --test uebergeben.
            REM Fuer die echte Ausfuehrung _test aus dem Dateinamen entfernen.
            REM ============================================================
            
            chcp 65001 >nul
            cd /d "%~dp0"
            
            echo %~n0 | find /i "_test" >nul
            
            if not errorlevel 1 (
                py "005_sendto_elemente_mit_praefix_umbenennen.py" --test %*
                REM Alternative, falls py nicht funktioniert:
                REM python "005_sendto_elemente_mit_praefix_umbenennen.py" --test %*
            ) else (
                py "005_sendto_elemente_mit_praefix_umbenennen.py" %*
                REM Alternative, falls py nicht funktioniert:
                REM python "005_sendto_elemente_mit_praefix_umbenennen.py" %*
            )

            Variante 3: Dateien in ausgewählten Ordnern über SendTo umbenennen

            Diese Variante erwartet einen oder mehrere Ordner. Sie benennt nur Dateien um, die direkt in diesen Ordnern liegen. Die übergebenen Ordner selbst und vorhandene Unterordner bleiben unverändert. Dateien innerhalb von Unterordnern werden nicht rekursiv erfasst.

            Der komplette Code der SendTo-Ordnerinhalt-Python-Datei

            # ============================================================
            # TOPTORIALS OFFICE - Python Grundkurs
            # Script: 005_sendto_ordnerinhalt_mit_praefix_umbenennen.py
            # Beschreibung: Benennt Dateien in über SendTo übergebenen Ordnern mit einem Präfix um.
            # Autor: Chris
            # YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
            # Webseite: https://www.toptorials.com
            # Version: 1.0
            # Stand: 2026-08-12
            # ============================================================
            
            from datetime import datetime
            from pathlib import Path
            import subprocess
            import sys
            
            
            print()
            
            argumente = sys.argv[1:]
            testmodus = "--test" in argumente
            
            
            # ------------------------------------------------------------
            # Das Argument "--test" aus den übrigen Argumenten herausfiltern
            # ------------------------------------------------------------
            
            # Ausführlich geschrieben ist dieser Ablauf leichter verständlich.
            
            argumente_ohne_test = []
            
            for argument in argumente:
                if argument != "--test":
                    argumente_ohne_test.append(argument)
            
            argumente = argumente_ohne_test
            
            
            # Die entsprechende Kurzschreibweise nennt man List Comprehension.
            
            # argumente = [argument for argument in argumente if argument != "--test"]
            
            
            # ------------------------------------------------------------
            # Prüfen, ob mindestens ein Element übergeben wurde
            # ------------------------------------------------------------
            
            if not argumente:
                print("Bitte sende mindestens einen Ordner an dieses Skript.")
                print()
                print("Du kannst einen oder mehrere Ordner im Explorer markieren,")
                print("rechts anklicken und anschließend 'Senden an' verwenden.")
                print()
                input("Drücke Enter zum Beenden")
                sys.exit()
            
            
            # ------------------------------------------------------------
            # Gewünschte Präfixvariante auswählen
            # Wichtig: Immer nur EINE der folgenden Varianten aktiv lassen.
            # ------------------------------------------------------------
            
            # Variante 1: Aktuelles Datum
            praefix = datetime.now().strftime("%Y-%m-%d_")
            
            # Variante 2: Aktuelles Datum und aktuelle Uhrzeit
            # praefix = datetime.now().strftime("%Y-%m-%d_%H-%M-%S_")
            
            # Variante 3: Eigener Text
            # praefix = "Ausgaben_"
            
            
            # ------------------------------------------------------------
            # Welche zusätzliche Ausgabe soll erstellt werden?
            # Wichtig: Immer nur EINE der folgenden Varianten aktiv lassen.
            # ------------------------------------------------------------
            
            # Variante 1: Nur Bildschirmausgabe
            logdatei_erstellen = False
            zwischenablage_verwenden = False
            
            # Variante 2: Logdatei erstellen
            # logdatei_erstellen = True
            # zwischenablage_verwenden = False
            
            # Variante 3: Nur in die Zwischenablage kopieren
            # logdatei_erstellen = False
            # zwischenablage_verwenden = True
            
            # Variante 4: Logdatei erstellen und in die Zwischenablage kopieren
            # logdatei_erstellen = True
            # zwischenablage_verwenden = True
            
            
            # ------------------------------------------------------------
            # Präfix und Modus vorbereiten
            # ------------------------------------------------------------
            
            ungueltige_zeichen = '<>:"/\\|?*'
            
            if not praefix.strip() or any(zeichen in praefix for zeichen in ungueltige_zeichen):
                print("FEHLER: Das eingestellte Präfix ist leer oder enthält ungültige Zeichen.")
                print()
                input("Drücke Enter zum Beenden")
                sys.exit()
            
            if testmodus:
                modus_text = "TESTMODUS"
            else:
                modus_text = "ECHTMODUS"
            
            anzahl_umbenannt = 0
            anzahl_uebersprungen = 0
            anzahl_fehler = 0
            anzahl_ordner = 0
            protokoll = []
            plaene = []
            
            protokoll.append("Dateien in übergebenen Ordnern werden mit einem Präfix umbenannt.")
            protokoll.append(f"Modus: {modus_text}")
            protokoll.append(f"Präfix: {praefix}")
            protokoll.append("")
            
            print("Dateien in übergebenen Ordnern werden mit einem Präfix umbenannt...")
            print()
            print(f"Modus: {modus_text}")
            print(f"Präfix: {praefix}")
            print()
            
            
            # ------------------------------------------------------------
            # Ordner und direkt enthaltene Dateien erfassen
            # Unterordner werden nicht durchsucht.
            # Doppelt übergebene Pfade werden nur einmal verarbeitet.
            # ------------------------------------------------------------
            
            eindeutige_argumente = []
            bereits_vorhanden = set()
            
            for element_pfad in argumente:
                vergleichs_pfad = str(Path(element_pfad).absolute()).casefold()
            
                if vergleichs_pfad not in bereits_vorhanden:
                    bereits_vorhanden.add(vergleichs_pfad)
                    eindeutige_argumente.append(element_pfad)
            
            for element_pfad in eindeutige_argumente:
                ordner = Path(element_pfad)
            
                if not ordner.is_dir():
                    meldung = (
                        f'ÜBERSPRUNGEN: Der übergebene Pfad ist kein Ordner: "{element_pfad}"'
                    )
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_uebersprungen += 1
                    continue
            
                try:
                    ordner = ordner.resolve()
                    dateien = []
            
                    for pfad in ordner.iterdir():
                        if pfad.is_file():
                            dateien.append(pfad)
            
                    anzahl_ordner += 1
            
                    print("Ordner wird verarbeitet:")
                    print(ordner)
                    print()
            
                    protokoll.append(f"Verarbeiteter Ordner: {ordner}")
                except OSError as fehler:
                    meldung = (
                        f'FEHLER: Ordnerinhalt konnte nicht gelesen werden: "{element_pfad}". '
                        f"Grund: {fehler}"
                    )
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_fehler += 1
                    continue
            
                for datei in dateien:
                    if datei.name.casefold().startswith(praefix.casefold()):
                        meldung = (
                            f'ÜBERSPRUNGEN: "{datei}" - '
                            "Präfix ist bereits am Anfang enthalten"
                        )
                        print(meldung)
                        protokoll.append(meldung)
                        anzahl_uebersprungen += 1
                        continue
            
                    neuer_name = praefix + datei.name
                    ziel_pfad = ordner / neuer_name
            
                    if ziel_pfad.exists():
                        meldung = (
                            f'ÜBERSPRUNGEN: "{datei}" - '
                            f'Zieldatei existiert bereits: "{ziel_pfad}"'
                        )
                        print(meldung)
                        protokoll.append(meldung)
                        anzahl_uebersprungen += 1
                        continue
            
                    plaene.append(
                        {
                            "quelle": datei,
                            "alter_name": datei.name,
                            "neuer_name": neuer_name,
                            "ziel": ziel_pfad,
                        }
                    )
            
                protokoll.append("")
            
            
            # ------------------------------------------------------------
            # Sicherheitsabfrage bei der echten Ausführung
            # ------------------------------------------------------------
            
            if not testmodus and plaene:
                print("ACHTUNG: Dieses Skript wird Dateien in den übergebenen Ordnern wirklich umbenennen.")
                print()
            
                antwort = input("Zum Fortfahren JA eingeben: ")
            
                if antwort.upper() != "JA":
                    print()
                    print("Abgebrochen.")
                    print()
                    input("Drücke Enter zum Beenden")
                    sys.exit()
            
                print()
            
            
            # ------------------------------------------------------------
            # Dateien umbenennen
            # ------------------------------------------------------------
            
            for plan in plaene:
                if testmodus:
                    meldung = (
                        f'WÜRDE UMBENENNEN: "{plan["quelle"]}" '
                        f'zu "{plan["ziel"]}"'
                    )
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_umbenannt += 1
                    continue
            
                try:
                    plan["quelle"].rename(plan["ziel"])
                    meldung = f'UMBENANNT: "{plan["quelle"]}" zu "{plan["ziel"]}"'
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_umbenannt += 1
                except OSError as fehler:
                    meldung = (
                        f'FEHLER: "{plan["quelle"]}" konnte nicht umbenannt werden. '
                        f"Grund: {fehler}"
                    )
                    print(meldung)
                    protokoll.append(meldung)
                    anzahl_fehler += 1
            
            
            # ------------------------------------------------------------
            # Zusammenfassung
            # ------------------------------------------------------------
            
            protokoll.append("")
            protokoll.append("Fertig.")
            
            print()
            print("Fertig.")
            print()
            
            meldung_ordner = f"Verarbeitete Ordner: {anzahl_ordner}"
            print(meldung_ordner)
            protokoll.append(meldung_ordner)
            
            if testmodus:
                meldung_1 = f"Anzahl Dateien, die umbenannt würden: {anzahl_umbenannt}"
                meldung_2 = f"Anzahl übersprungen: {anzahl_uebersprungen}"
                meldung_3 = f"Anzahl Fehler: {anzahl_fehler}"
            
                print(meldung_1)
                print(meldung_2)
                print(meldung_3)
                print()
                print("Es wurden keine Dateien umbenannt.")
                print("Wenn alles richtig aussieht, entferne _test aus dem Namen der Starter-Batchdatei.")
            
                protokoll.append(meldung_1)
                protokoll.append(meldung_2)
                protokoll.append(meldung_3)
                protokoll.append("Es wurden keine Dateien umbenannt.")
            else:
                meldung_1 = f"Anzahl umbenannt: {anzahl_umbenannt}"
                meldung_2 = f"Anzahl übersprungen: {anzahl_uebersprungen}"
                meldung_3 = f"Anzahl Fehler: {anzahl_fehler}"
            
                print(meldung_1)
                print(meldung_2)
                print(meldung_3)
            
                protokoll.append(meldung_1)
                protokoll.append(meldung_2)
                protokoll.append(meldung_3)
            
            
            # ------------------------------------------------------------
            # Optionale Ausgabe als Logdatei und in die Zwischenablage
            # ------------------------------------------------------------
            
            protokoll_text = "\n".join(protokoll)
            zeitstempel = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
            skript_ordner = Path(__file__).resolve().parent
            logdatei = skript_ordner / f"umbenennprotokoll_ordnerinhalt_{zeitstempel}.log"
            
            if logdatei_erstellen:
                try:
                    logdatei.write_text(protokoll_text, encoding="utf-8")
                    print()
                    print("Das Protokoll wurde erstellt:")
                    print(logdatei)
                except OSError as fehler:
                    print()
                    print(f"FEHLER: Das Protokoll konnte nicht erstellt werden. Grund: {fehler}")
            
            if zwischenablage_verwenden:
                try:
                    subprocess.run(
                        "clip",
                        input=protokoll_text,
                        text=True,
                        encoding="utf-8",
                        check=True,
                    )
                    print()
                    print("Das Protokoll wurde zusätzlich in die Zwischenablage kopiert.")
                except (OSError, subprocess.CalledProcessError) as fehler:
                    print()
                    print(f"FEHLER: Das Protokoll konnte nicht kopiert werden. Grund: {fehler}")
            
            print()
            input("Drücke Enter zum Beenden")

            Code der SendTo-Ordnerinhalt-Datei erklärt

            Nur Ordner akzeptieren

            ordner = Path(element_pfad)
            
            if not ordner.is_dir():

            is_dir() liefert nur bei einem vorhandenen Ordner True. Übergebene Dateien und nicht vorhandene Pfade werden übersprungen.

            Nur direkt enthaltene Dateien erfassen

            for pfad in ordner.iterdir():
                if pfad.is_file():
                    dateien.append(pfad)

            iterdir() liefert die Elemente direkt innerhalb des Ordners. Es durchsucht keine Unterordner. is_file() übernimmt ausschließlich Dateien in die Liste.

            Mehrere Ordner gemeinsam vorbereiten

            Jeder gültige Ordner wird nacheinander gelesen. Die gefundenen Dateien werden geprüft und als Dictionaries in der gemeinsamen Liste plaene gespeichert. Erst nachdem alle übergebenen Ordner untersucht wurden, erscheint im Echtmodus eine einzige Sicherheitsabfrage.

            Pläne im Test- oder Echtmodus ausführen

            for plan in plaene:
                if testmodus:
                    ...
                    continue
            
                try:
                    plan["quelle"].rename(plan["ziel"])

            Im Testmodus wird nur eine Meldung erzeugt. continue beginnt danach sofort mit dem nächsten Plan. Im Echtmodus führt rename() die Umbenennung aus.

            Der komplette Code der SendTo-Ordnerinhalt-Starter-Batchdatei

            @echo off
            REM ============================================================
            REM TOPTORIALS OFFICE - Python Grundkurs
            REM Script: 005_sendto_ordnerinhalt_mit_praefix_umbenennen_starter_batch_test.bat
            REM Beschreibung: Startet die SendTo-Variante für Ordnerinhalte.
            REM Autor: Chris
            REM YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
            REM Webseite: https://www.toptorials.com
            REM Version: 1.0
            REM Stand: 2026-08-12
            REM
            REM Hinweis:
            REM Solange _test im Dateinamen steht, wird --test uebergeben.
            REM Fuer die echte Ausfuehrung _test aus dem Dateinamen entfernen.
            REM ============================================================
            
            chcp 65001 >nul
            cd /d "%~dp0"
            
            echo %~n0 | find /i "_test" >nul
            
            if not errorlevel 1 (
                py "005_sendto_ordnerinhalt_mit_praefix_umbenennen.py" --test %*
                REM Alternative, falls py nicht funktioniert:
                REM python "005_sendto_ordnerinhalt_mit_praefix_umbenennen.py" --test %*
            ) else (
                py "005_sendto_ordnerinhalt_mit_praefix_umbenennen.py" %*
                REM Alternative, falls py nicht funktioniert:
                REM python "005_sendto_ordnerinhalt_mit_praefix_umbenennen.py" %*
            )

            Code der SendTo-Starter-Batchdateien erklärt

            Der entscheidende Unterschied zur einfachen Starter-Batchdatei ist %*:

            py "005_sendto_elemente_mit_praefix_umbenennen.py" --test %*

            beziehungsweise:

            py "005_sendto_ordnerinhalt_mit_praefix_umbenennen.py" --test %*

            %* steht für alle Argumente, die an die Batchdatei übergeben wurden. Über SendTo sind das die vollständigen Pfade der ausgewählten Dateien und Ordner. Anführungszeichen in der Übergabe schützen Pfade mit Leerzeichen.

            SendTo-Verknüpfungen einrichten

            Für beide SendTo-Varianten wird jeweils eine Verknüpfung zur passenden Starter-Batchdatei angelegt.

            1. Die Starter-Batchdatei im Kursordner mit der rechten Maustaste anklicken.
            2. Verknüpfung erstellen auswählen.
            3. Die neue Verknüpfung verständlich benennen, zum Beispiel Python 005 - Elemente mit Präfix umbenennen TEST.
            4. Mit Windows-Taste + R das Fenster Ausführen öffnen.
            5. shell:sendto eingeben und mit Enter bestätigen.
            6. Die Verknüpfung in diesen Ordner verschieben.

            Für die Ordnerinhalt-Variante wird derselbe Ablauf mit ihrer Starter-Batchdatei wiederholt.

            Solange _test im Namen der tatsächlichen Starter-Batchdatei steht, wird der Testmodus verwendet. Entscheidend ist nicht der Name der Verknüpfung, sondern der Name der Batchdatei, auf die sie verweist.

            Logdateien und Zwischenablage

            Die Liste protokoll sammelt alle wichtigen Meldungen. Anschließend verbindet:

            protokoll_text = "\n".join(protokoll)

            alle Listeneinträge mit Zeilenumbrüchen zu einem Text.

            Die Logdatei wird mit UTF-8 gespeichert:

            logdatei.write_text(protokoll_text, encoding="utf-8")

            Für die Windows-Zwischenablage startet subprocess.run() das Programm clip und übergibt den Protokolltext über die Standardeingabe.

            Typische Meldungen

            WÜRDE UMBENENNEN

            Der Testmodus zeigt eine geplante Umbenennung an. Es wurde nichts verändert.

            UMBENANNT

            Die Umbenennung wurde im Echtmodus erfolgreich ausgeführt.

            ÜBERSPRUNGEN

            Das Element wurde absichtlich nicht verändert, zum Beispiel wegen eines vorhandenen Präfixes, eines bestehenden Zielpfades, einer geschützten Kursdatei oder eines ungeeigneten Übergabetyps.

            FEHLER

            Bei einer Datei- oder Ordneroperation ist eine Ausnahme aufgetreten. Der Grund wird hinter der Meldung ausgegeben.

            Typische Fehler und Lösungen

            Python oder der Python Launcher wurde nicht gefunden

            Prüfe mit py --version und python --version, welcher Startbefehl verfügbar ist. Falls py nicht funktioniert, kann in der Starter-Batchdatei die vorbereitete Alternative mit python aktiviert werden.

            Die Python-Datei wurde nicht gefunden

            Python-Datei und Starter-Batchdatei müssen im gleichen Variantenordner liegen. Außerdem muss der im Batchcode verwendete Dateiname exakt stimmen.

            Die SendTo-Datei wurde direkt gestartet

            Die SendTo-Varianten benötigen mindestens einen übergebenen Pfad. Verwende sie über eine Verknüpfung im Menü Senden an.

            Eine Datei wurde bei der Ordnerinhalt-Variante übersprungen

            Diese Variante akzeptiert als übergebene Elemente nur Ordner. Einzelne Dateien werden absichtlich übersprungen.

            Dateien in Unterordnern wurden nicht umbenannt

            Das ist beabsichtigt. iterdir() erfasst nur die direkt enthaltenen Dateien. Unterordner werden nicht rekursiv durchsucht.

            Eine Datei wurde wegen eines vorhandenen Ziels übersprungen

            Im gleichen Ordner existiert bereits ein Element mit dem geplanten neuen Namen. Das Skript überschreibt dieses Ziel nicht.

            Eine Datei erhielt beim zweiten Lauf ein weiteres Präfix

            Das Skript erkennt nur das momentan eingestellte Präfix am Anfang des Namens. Ändert sich das Datum, die Uhrzeit oder der eigene Text, unterscheidet sich auch das Präfix und kann erneut ergänzt werden.

            Das Präfix wird als ungültig gemeldet

            Das Präfix ist leer, besteht nur aus Leerzeichen oder enthält mindestens eines der unter Windows unzulässigen Dateinamenzeichen.

            Keine Logdatei wurde erstellt

            In der Standardkonfiguration sind Logdatei und Zwischenablage ausgeschaltet. Aktiviere die gewünschte Variante über die beiden Wahrheitswerte.

            Die Eingabe ja wurde trotzdem nicht akzeptiert

            In dieser Python-Version wird antwort.upper() != "JA" verwendet. Dadurch werden JA, Ja und ja akzeptiert. Zusätzliche Leerzeichen werden jedoch nicht automatisch entfernt.

            Umlaute oder Sonderzeichen werden falsch angezeigt

            Speichere Python- und Batchdateien als UTF-8. Die Starter-Batchdateien stellen die Windows-Konsole zusätzlich mit chcp 65001 auf die UTF-8-Codepage um.

            Nützliche Python-Begriffe aus diesem Teil

            sys.argv
            Liste der Startargumente des Python-Programms.
            
            Path.cwd()
            Liefert den aktuellen Arbeitsordner als Path-Objekt.
            
            __file__
            Enthält den Pfad der aktuell ausgeführten Python-Datei.
            
            resolve()
            Ermittelt einen vollständigen aufgelösten Pfad.
            
            absolute()
            Erstellt eine absolute Darstellung eines Pfades.
            
            parent
            Liefert den übergeordneten Ordner eines Pfades.
            
            name
            Liefert den letzten Namensteil eines Pfades.
            
            iterdir()
            Durchläuft die direkt enthaltenen Elemente eines Ordners.
            
            is_file()
            Prüft, ob ein Pfad eine vorhandene Datei ist.
            
            is_dir()
            Prüft, ob ein Pfad ein vorhandener Ordner ist.
            
            exists()
            Prüft, ob ein Pfad vorhanden ist.
            
            rename()
            Benennt eine Datei oder einen Ordner zum angegebenen Zielpfad um.
            
            strftime()
            Formatiert Datum und Uhrzeit als Text.
            
            strip()
            Entfernt Leerraum am Anfang und Ende eines Textes.
            
            lower()
            Wandelt Buchstaben in Kleinbuchstaben um.
            
            upper()
            Wandelt Buchstaben in Großbuchstaben um.
            
            casefold()
            Vereinheitlicht Text besonders gründlich für Vergleiche ohne Groß- und Kleinschreibung.
            
            startswith()
            Prüft, ob ein Text mit einem bestimmten Text beginnt.
            
            append()
            Fügt einer Liste einen neuen Eintrag hinzu.
            
            set()
            Erzeugt eine Menge, in der jeder Wert nur einmal vorkommt.
            
            add()
            Fügt einem Set einen Wert hinzu.
            
            Dictionary
            Speichert zusammengehörige Werte unter benannten Schlüsseln.
            
            List Comprehension
            Kurze Python-Schreibweise zum Erzeugen oder Filtern einer Liste.
            
            lambda
            Kurze anonyme Funktion, die hier den Sortierwert liefert.
            
            sort()
            Sortiert eine vorhandene Liste.
            
            try und except
            Fangen erwartbare Fehler ab und ermöglichen eine kontrollierte Behandlung.
            
            OSError
            Basisklasse für viele typische Datei- und Betriebssystemfehler.
            
            subprocess.run()
            Startet ein externes Programm und kann Daten an dieses übergeben.
            
            write_text()
            Schreibt Text über ein Path-Objekt in eine Datei.

            Wichtige Batch-Begriffe aus diesem Teil

            @echo off
            Unterdrückt die automatische Anzeige der Batchbefehle.
            
            REM
            Kennzeichnet einen Kommentar in einer Batchdatei.
            
            chcp 65001
            Aktiviert die UTF-8-Codepage für die Konsole.
            
            %~dp0
            Laufwerk und Ordner der laufenden Batchdatei.
            
            %~n0
            Name der laufenden Batchdatei ohne Dateiendung.
            
            %*
            Alle an die Batchdatei übergebenen Argumente.
            
            find /i
            Sucht einen Text ohne Beachtung der Groß- und Kleinschreibung.
            
            errorlevel
            Enthält den Rückgabewert des zuletzt ausgeführten Programms.
            
            py
            Startet Python über den Python Launcher.
            
            --test
            Startargument, mit dem unser Python-Skript den Testmodus erkennt.

            Was haben wir gelernt?

            In diesem Teil haben wir:

            Dateien und Ordner mit einem Präfix umbenannt
            Datum, Uhrzeit und eigenen Text als Präfix verwendet
            Datumsformate mit datetime und strftime() erstellt
            Testmodus und Echtmodus eingesetzt
            Startargumente mit sys.argv verarbeitet
            --test mit einer ausführlichen Schleife herausgefiltert
            die Kurzschreibweise List Comprehension kennengelernt
            Pfade mit pathlib und Path verarbeitet
            __file__ und weitere Dunder-Namen kennengelernt
            Groß- und Kleinschreibung mit casefold() vereinheitlicht
            doppelte Pfade mit set() erkannt
            Umbenennungen in Dictionaries geplant
            Pläne mit sort() und lambda nach Pfadlänge sortiert
            Dateien und Ordner mit rename() umbenannt
            Fehler mit try und except behandelt
            Logdateien und Zwischenablage optional verwendet
            SendTo-Verknüpfungen für den Windows-Explorer eingerichtet

            Damit steht ein vielseitiges Python-Werkzeug zur Verfügung, das sich zuerst sicher testen und anschließend für verschiedene Umbenennungsaufgaben anpassen lässt.

            Video zu diesem Tutorial:

             

            Das könnte Dich auch interessieren

            Keine Einträge gefunden

             

            Schreibe einen Kommentar Antwort abbrechen

            Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

            INTERESSANTE SEITEN

            • TUTORIALS SCHNELLER FINDEN
            • SCHNELLER RECHNEN LERNEN
            • MATHE AUFGABEN GENERATOR
            • LINIEN UND KARO GENERATOR
            • VORLAGEN ZUM AUSDRUCKEN
            • BINGO-SCHEIN-GENERATOR
            • MEINE WUNSCHLISTE
            • Symbole zum Kopieren

            Content

            • Microsoft Excel Tutorials
            • Microsoft Excel VBA Tutorials
            • Microsoft Word Tutorials
            • Microsoft Powerpoint Tutorials
            • Microsoft Windows 10 Tutorials
            • Google Tabellen Tutorials
            • Google Tabellen Script Tutorials
            • Google Docs Tutorials
            • LibreOffice Calc Tutorials
            • Libre Office Writer Tutorials
            • LibreOffice Impress Tutorials
            • OpenOffice Calc Tutorials
            • OpenOffice Writer Tutorials
            • OpenOffice Impress Tutorials
            • WPS Spreadsheets Tutorials
            • WPS Spreadsheets Tutorials

            Neue Beiträge

            • Python Grundkurs 005: Dateien mit einem Präfix umbenennen
            • PowerShell 7 Grundkurs 005: Dateien mit einem Präfix umbenennen
            • Batch Grundkurs 005: Dateien mit Präfix umbenennen
            • Python Grundkurs 004: Dateien automatisch nach Dateityp sortieren
            • PowerShell 7 Grundkurs 004: Dateien automatisch nach Dateityp sortieren

            Neue Kommentare

            • Chris zu Python in LibreOffice Calc: Formular auslesen und auswerten
            • Detlef M. zu Python in LibreOffice Calc: Formular auslesen und auswerten
            • Johannes Hanel zu Verknüpfungen in LibreOffice Calc
            • Holfrie zu Symbole vergrößern von der Benutzeroberfläche (OpenOffice)
            • Bianca zu Tutorial Wunsch Liste
            • Wolfgang Dehmer zu Funktion zeitlich gesteuert ausführen (Google Tabellen) Script

            Schlagwörter-Wolke

            anfänger Anleitung anpassen ausrechnen auswahlliste Bedingte Formatierung berechnen Calc Datum Download Dropdownliste einfügen entfernen erstellen Excel FreeOffice Funktion google hinzufügen Jahresplan Kalender Lernvideo LibreOffice löschen Makro markieren Microsoft OpenOffice PlanMaker programmierung script spreadsheets Sverweis Tabelle tabellen Tutorial VBA Video Wenn Wenn Funktion Word wps spreadsheets Zeilen Zelle Zellen
            KONTAKT   IMPRESSUM    DATENSCHUTZERKLÄRUNG    HAFTUNGSAUSSCHLUSS (Disclaimer)   © copyright TOPTORIALS