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

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.
- Die Starter-Batchdatei im Kursordner mit der rechten Maustaste anklicken.
- Verknüpfung erstellen auswählen.
- Die neue Verknüpfung verständlich benennen, zum Beispiel
Python 005 - Elemente mit Präfix umbenennen TEST. - Mit
Windows-Taste + Rdas Fenster Ausführen öffnen. shell:sendtoeingeben und mit Enter bestätigen.- 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

