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

            Python Grundkurs Teil 008: Text in Dateinamen ersetzen

            • Startseite
            • Tutorials Windows Automatisierung Python Grundkurs
            • Python Grundkurs Teil 008: Text in Dateinamen ersetzen

            Python Grundkurs Teil 008: Text in Dateinamen ersetzen

            Worum geht es in diesem Teil?

            In diesem Teil des Python-Grundkurses ersetzen oder entfernen wir einen bestimmten Text automatisch in mehreren Dateinamen. Suchtext und Ersatztext werden beim Start eingegeben. Die Skripte ermitteln anschließend zunächst alle geplanten Zielnamen, bevor eine Datei verändert wird.

            Aus einer Datei wie:

            MeinBeispiel.txt

            wird mit dem Suchtext Mein und dem Ersatztext Dein beispielsweise:

            DeinBeispiel.txt

            Bleibt der Ersatztext leer, wird der Suchtext entfernt. Aus MeinBeispiel.txt soll dann Beispiel.txt werden – sofern dieser Zielname noch frei ist.

            Beispiele für Ersetzungen

            Beispiele für Ersetzungen

            Wir verwenden zwei Varianten:

            1. Text in den Dateinamen des aktuellen Ordners ersetzen oder entfernen.
            2. Dateien und Ordner über das Windows-Menü Senden an übergeben und deren Dateinamen bearbeiten.

            Beide Varianten besitzen einen Testmodus, eine vollständige Vorschau und eine Konfliktauflösung mit nummerierten Zielnamen.

            Was ist das Ziel?

            Wiederkehrende Namensbestandteile lassen sich mit einem einzigen Durchlauf ändern, ohne jede Datei einzeln umzubenennen. Das eignet sich beispielsweise für alte Projektbezeichnungen, überflüssige Zusätze oder Schreibweisen, die vereinheitlicht werden sollen.

            Die Dateien bleiben in ihren bisherigen Ordnern. Ist ein gewünschter Zielname schon vorhanden, ergänzt Python automatisch _001, _002 und weitere Nummern.

            Warum ist dieser Teil wichtig?

            In diesem Tutorial verbinden wir mehrere wichtige Python-Grundlagen:

            • input() liest Suchtext, Ersatztext und Sicherheitsbestätigung ein.
            • sys.argv übernimmt den Testschalter und die bei SendTo übergebenen Pfade.
            • re.escape() maskiert besondere Regex-Zeichen im eingegebenen Suchtext.
            • re.IGNORECASE ermöglicht die Suche ohne Beachtung der Groß- und Kleinschreibung.
            • lambda übergibt den Ersatztext wörtlich an sub().
            • pathlib.Path verarbeitet Ordner, Dateinamen, Endungen und vollständige Pfade.
            • Listen mit Dictionaries speichern die geplanten Umbenennungen.
            • Sets verhindern doppelte Quelldateien und reservieren bereits geplante Ziele.
            • rename() führt die bestätigten Änderungen aus.

            Hinweis zur Kursreihe

            Dieses Tutorial gehört zum Python-Grundkurs. Der Aufbau orientiert sich an den entsprechenden Teilen für Batch und PowerShell 7. Dadurch lassen sich die verschiedenen Schreibweisen und Lösungswege besonders gut vergleichen.

            Wir verwenden eine übersichtliche Grundkurs-Version mit Bildschirmausgabe. Eine zusätzliche Logdatei oder Ausgabe in die Zwischenablage ist in diesen beiden Skripten nicht enthalten.

            Downloads zu diesem Teil

            Dateien für Python Grundkurs Teil 008:
            Download Python Grundkurs: 008_Text_in_Dateinamen_ersetzen als ZIP-Datei.Entpacken nach:

            C:\TOPTORIALS_CODE\020_Python_Grundkurs

            Der Hauptordner für diesen Teil lautet:

            C:\TOPTORIALS_CODE\020_Python_Grundkurs\008_Text_in_Dateinamen_ersetzen

            Testumgebung zum Mitmachen

            Verwende für die ersten Durchläufe ausschließlich Kopien unwichtiger Dateien. Dafür kannst du wieder die vorbereitete Testumgebung der Kursreihe verwenden.

            Testumgebung für Windows-Automatisierung:Download TOPTORIALS_Testdaten_Windows_Automatisierung_V001.zip

            Entpacken nach:

            C:\TOPTORIALS_CODE\1000_TESTBEREICH

            Für Python befindet sich der Testbereich unter:

            C:\TOPTORIALS_CODE\1000_TESTBEREICH\TOPTORIALS_Testdaten_Windows_Automatisierung_Python_V001\008_Text_in_Dateinamen_ersetzen

            Sicherheitshinweis

            Wichtig:Prüfe vor dem ersten Start den tatsächlichen Namen der Starter-Batchdatei. Nur wenn darin _test vorkommt, wird --test an Python übergeben.

            Im Konsolenfenster muss Testmodus: JA erscheinen. Dann werden lediglich die geplanten Umbenennungen angezeigt.

            Für den Echtmodus wird _test aus dem Namen der Starter-Batchdatei entfernt. Vor der tatsächlichen Ausführung muss zusätzlich mit JA bestätigt werden.

            Die Ersetzung betrifft den vollständigen Dateinamen und damit auch die Dateiendung. Eine umbenannte Endung verändert nicht das Dateiformat oder den Dateiinhalt.

            Sichere wichtige Dateien vorher. Eine automatische Rückgängig-Funktion ist nicht eingebaut. Die Nutzung erfolgt auf eigene Verantwortung.

            Voraussetzungen

            • Windows 10 oder Windows 11
            • installiertes Python 3 und der Python Launcher py
            • ausreichende Rechte zum Umbenennen der betreffenden Dateien
            • Python-Skript und passende Starter-Batchdatei gemeinsam im jeweiligen Ordner

            Enthaltene Ordner und Dateien

            Die beiden Varianten liegen in diesen Kursordnern:

            C:\TOPTORIALS_CODE\020_Python_Grundkurs\008_Text_in_Dateinamen_ersetzen\01_Einfach
            
            C:\TOPTORIALS_CODE\020_Python_Grundkurs\008_Text_in_Dateinamen_ersetzen\02_SendTo_Text_ersetzen
            008_Text_in_Dateinamen_ersetzen
            │
            ├── 01_Einfach
            │   ├── 008_text_in_dateinamen_ersetzen.py
            │   └── 008_text_in_dateinamen_ersetzen_starter_batch_test.bat
            │
            └── 02_SendTo_Text_ersetzen
                ├── 008_sendto_text_in_dateinamen_ersetzen.py
                └── 008_sendto_text_in_dateinamen_ersetzen_starter_batch_test.bat

            Für den Echtmodus wird ausschließlich _test aus dem Namen des jeweiligen Starters entfernt. Die Namen der Python-Dateien bleiben unverändert, weil die Batchdateien genau diese Dateien aufrufen.

            Wie funktionieren Suche und Ersetzung?

            Suchtext und Ersatztext eingeben

            Beide Skripte stellen dieselben Fragen:

            Alter Text / Suchtext:
            Neuer Text / Ersatztext:

            Ein leerer Suchtext beendet den Durchlauf. Ein leerer Ersatztext ist dagegen erlaubt. Drücke bei der zweiten Frage einfach Enter, um den gefundenen Text zu entfernen.

            Wörtliche Suche ohne Beachtung der Groß- und Kleinschreibung

            suchmuster = re.compile(re.escape(alter_text), re.IGNORECASE)

            re.escape(alter_text) maskiert Zeichen, die in regulären Ausdrücken normalerweise eine besondere Bedeutung besitzen. Ein eingegebener Punkt bleibt dadurch ein normaler Punkt und ein Sternchen würde als normales Sternchen gesucht.

            re.IGNORECASE sorgt dafür, dass beispielsweise IMG, Img und img als Treffer erkannt werden.

            Warum wird beim Ersetzen eine lambda-Funktion verwendet?

            neuer_name = suchmuster.sub(lambda _: neuer_text, datei.name)

            sub() ersetzt alle gefundenen Textstellen. Die kleine Funktion lambda _: neuer_text gibt bei jedem Treffer genau den eingegebenen Ersatztext zurück.

            Dadurch wird auch der Ersatztext wörtlich behandelt. Zeichen, die in einem normalen Regex-Ersatztext besondere Funktionen haben könnten, werden nicht als zusätzliche Anweisung ausgewertet.

            Beispiele für die Ersetzung

            Ausgangsname Suchtext Ersatztext Gewünschter Zielname
            MeinBeispiel.txt Mein Dein DeinBeispiel.txt
            MeinBeispiel.txt Mein leer Beispiel.txt
            Alt_alt_Bericht.txt alt Neu Neu_Neu_Bericht.txt
            Bericht.TXT .txt .md Bericht.md

            Die Beispiele setzen voraus, dass der gewünschte Zielname noch frei ist.

            Was passiert bei einem leeren Basisnamen?

            Das Skript führt die Ersetzung zusätzlich im Basisnamen ohne die letzte Dateiendung aus. Wird dieser Basisname vollständig entfernt, verwendet es Unbenannt mit der ursprünglichen Endung.

            Beispiel.txt → Unbenannt.txt

            Ist Unbenannt.txt bereits vorhanden, greift auch hier die automatische Nummerierung.

            Welche Dateien werden ausgelassen?

            Diese ursprünglichen Dateiendungen sind ausgeschlossen:

            .bat, .cmd, .ps1, .py, .log

            Dadurch werden unter anderem die Starter-Batchdateien und Python-Skripte selbst nicht umbenannt. Die Prüfung erfolgt mit casefold() und unterscheidet deshalb nicht zwischen Groß- und Kleinschreibung.

            Dateien, deren Name durch die Ersetzung unverändert bleibt, werden ebenfalls übersprungen. Ordnernamen bleiben unverändert. Bei einem Ordner werden nur die direkt enthaltenen Dateien verarbeitet; tiefere Unterordner werden nicht durchsucht.

            Namenskonflikte und automatische Nummerierung

            Der gewünschte Zielname kann bereits vorhanden sein. In diesem Fall sucht get_freier_zielpfad() nach einem freien Ziel mit einer dreistelligen Nummer vor der Dateiendung.

            Beispiel: MeinBeispiel.txt und Beispiel.txt

            MeinBeispiel.txt
            Beispiel.txt

            Wir suchen Mein und lassen den Ersatztext leer. Weil Beispiel.txt bereits vorhanden ist, lautet das Ziel:

            MeinBeispiel.txt → Beispiel_001.txt

            Beispiel: _001 entfernen

            Ist Beispiel.txt frei, kann aus Beispiel_001.txt wieder Beispiel.txt werden.

            Existiert Beispiel.txt bereits, ist der gewünschte Name belegt. Auch Beispiel_001.txt ist während der Planung noch die vorhandene Quelldatei. Das nächste freie Ziel lautet deshalb:

            Beispiel_001.txt → Beispiel_002.txt

            Merke:Das Entfernen eines Nummernzusatzes garantiert keinen Dateinamen ohne Nummer. Ist dieser Name bereits belegt, muss das Skript einen anderen freien Namen verwenden.

            Bereits geplante Ziele berücksichtigen

            Während der Planung wurden die Dateien noch nicht umbenannt. Ein geplanter Zielpfad ist daher möglicherweise noch nicht im Dateisystem sichtbar. Das Set reservierte_ziele merkt sich solche Ziele trotzdem.

            reservierte_ziele = set()

            Vor dem Speichern eines Plans prüft die Funktion sowohl zielpfad.exists() als auch das Set. Dadurch können nicht zwei Dateien denselben Zielpfad erhalten.

            Testmodus und Echtmodus

            Der Ablauf ist bei beiden Varianten gleich:

            1. Der Starter prüft, ob sein eigener Dateiname _test enthält.
            2. Im Testmodus übergibt er --test an das Python-Skript.
            3. Python fragt Suchtext und Ersatztext ab.
            4. Die Dateien werden gesammelt und sämtliche Umbenennungen geplant.
            5. Quelle und Ziel jedes Plans werden angezeigt.
            6. Im Testmodus endet der Durchlauf ohne Veränderungen.
            7. Im Echtmodus werden die Pläne erst nach der Eingabe von JA ausgeführt.

            Beim erneuten Start für den Echtmodus werden Suchtext und Ersatztext erneut abgefragt und alle Pläne neu erzeugt. Kontrolliere deshalb auch diese Vorschau.

            Variante 1: Text im aktuellen Ordner ersetzen

            So wird die Variante angewendet

            Kopiere das Python-Skript und die Starter-Batchdatei aus 01_Einfach gemeinsam in den Ordner mit den zu bearbeitenden Testdateien.

            Starte zuerst:

            008_text_in_dateinamen_ersetzen_starter_batch_test.bat

            Prüfe die Anzeige Testmodus: JA, gib Suchtext und Ersatztext ein und kontrolliere anschließend alle Zielpfade.

            Für den Echtlauf entfernst du _test aus dem Namen der Batchdatei. Starte sie erneut und bestätige nur dann mit JA, wenn die Vorschau stimmt.

            Vollständiges Python-Skript

            Dateiname: 008_text_in_dateinamen_ersetzen.py

            # ============================================================
            # TOPTORIALS OFFICE - Python Grundkurs
            # Teil: 008 - Text in Dateinamen ersetzen
            # Script: 008_text_in_dateinamen_ersetzen.py
            # Beschreibung:
            # Ersetzt oder entfernt Text in den Dateinamen des aktuellen Ordners.
            # Die Ersetzung berücksichtigt auch die Dateiendung.
            # Autor: Chris
            # YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
            # Webseite: https://www.toptorials.com
            # Version: Grundkurs 1.0
            # Stand: 2026-09-01
            #
            # Hinweise:
            # - Benötigt Python 3.
            # - Mit --test werden die geplanten Umbenennungen nur angezeigt.
            # - Ohne --test erfolgt die Ausführung nach Bestätigung mit JA.
            # - Ein leerer Ersatztext entfernt alle gefundenen Textstellen.
            # - Die Suche ignoriert Groß- und Kleinschreibung.
            # - Unterordner werden nicht durchsucht oder umbenannt.
            # - .bat, .cmd, .ps1, .py und .log werden ausgeschlossen.
            # - Alle Umbenennungen werden vor der Ausführung geplant.
            # - Namenskonflikte erhalten Zusätze wie _001, _002 usw.
            # - Zuerst mit Testdateien arbeiten und wichtige Daten sichern.
            # - Die Nutzung erfolgt auf eigene Verantwortung.
            # ============================================================
            
            from pathlib import Path
            import re
            import sys
            
            
            # ------------------------------------------------------------
            # Hilfsfunktion: Einen freien Zielpfad ermitteln
            # ------------------------------------------------------------
            
            def get_freier_zielpfad(ordner, dateiname, quellpfad, reservierte_ziele):
                basis = Path(dateiname).stem
                endung = Path(dateiname).suffix
                zielname = dateiname
                nummer = 0
            
                while True:
                    zielpfad = ordner / zielname
                    vergleichs_ziel = str(zielpfad.absolute()).casefold()
                    vergleichs_quelle = str(quellpfad.absolute()).casefold()
            
                    eigene_datei = nummer == 0 and vergleichs_ziel == vergleichs_quelle
                    vorhanden = zielpfad.exists()
                    reserviert = vergleichs_ziel in reservierte_ziele
            
                    if (eigene_datei or not vorhanden) and not reserviert:
                        reservierte_ziele.add(vergleichs_ziel)
                        return zielpfad
            
                    nummer += 1
                    zielname = f"{basis}_{nummer:03d}{endung}"
            
            
            # ------------------------------------------------------------
            # Testmodus, Suchtext und Ersatztext vorbereiten
            # ------------------------------------------------------------
            
            testmodus = "--test" in sys.argv[1:]
            
            print()
            print("Text in Dateinamen ersetzen")
            print(
                "Ersetzt wird auch in der Dateiendung. "
                "Ein leerer Ersatztext entfernt den Suchtext."
            )
            print()
            print(f"Testmodus: {'JA' if testmodus else 'NEIN'}")
            print()
            
            alter_text = input("Alter Text / Suchtext: ")
            
            if alter_text == "":
                print("Kein Suchtext eingegeben. Abgebrochen.")
                sys.exit()
            
            neuer_text = input("Neuer Text / Ersatztext: ")
            print()
            
            ungueltige_zeichen = '<>:"/\\|?*'
            
            if any(zeichen in neuer_text for zeichen in ungueltige_zeichen) or any(
                ord(zeichen) < 32 for zeichen in neuer_text
            ):
                print("Der Ersatztext enthält unzulässige Zeichen. Es wurde nichts geändert.")
                sys.exit(1)
            
            # re.escape() behandelt den Suchtext wörtlich.
            # Die lambda-Funktion behandelt auch den Ersatztext wörtlich.
            suchmuster = re.compile(re.escape(alter_text), re.IGNORECASE)
            ausgeschlossene_endungen = (".bat", ".cmd", ".ps1", ".py", ".log")
            
            plaene = []
            reservierte_ziele = set()
            anzahl_umbenannt = 0
            anzahl_uebersprungen = 0
            anzahl_fehler = 0
            
            
            # ------------------------------------------------------------
            # Dateien im aktuellen Ordner erfassen
            # ------------------------------------------------------------
            
            basis_ordner = Path.cwd()
            print(f"Ordner: {basis_ordner}")
            print()
            
            try:
                dateien = sorted(
                    (pfad for pfad in basis_ordner.iterdir() if pfad.is_file()),
                    key=lambda pfad: str(pfad.absolute()).casefold(),
                )
            except OSError as fehler:
                print(f"FEHLER beim Lesen des Ordners: {fehler}")
                sys.exit(1)
            
            
            # ------------------------------------------------------------
            # Umbenennungen planen, noch keine Datei verändern
            # ------------------------------------------------------------
            
            for datei in dateien:
                if datei.suffix.casefold() in ausgeschlossene_endungen:
                    print(f"ÜBERSPRUNGEN: {datei.name} - ausgeschlossene Endung")
                    anzahl_uebersprungen += 1
                    continue
            
                neuer_name = suchmuster.sub(lambda _: neuer_text, datei.name)
                neue_basis = suchmuster.sub(lambda _: neuer_text, datei.stem)
            
                if neue_basis == "":
                    neuer_name = "Unbenannt" + datei.suffix
            
                if neuer_name == datei.name:
                    print(f"ÜBERSPRUNGEN: {datei.name} - keine Änderung")
                    anzahl_uebersprungen += 1
                    continue
            
                if not neuer_name or neuer_name.isspace() or neuer_name.endswith((".", " ")):
                    print(f"FEHLER: Ungültiger Zielname für {datei.name}")
                    anzahl_fehler += 1
                    continue
            
                try:
                    zielpfad = get_freier_zielpfad(
                        datei.parent,
                        neuer_name,
                        datei,
                        reservierte_ziele,
                    )
                    plaene.append({"quelle": datei, "ziel": zielpfad})
                except OSError as fehler:
                    print(f"FEHLER beim Planen von '{datei}': {fehler}")
                    anzahl_fehler += 1
            
            
            # ------------------------------------------------------------
            # Vorschau anzeigen - auch vor einer echten Ausführung
            # ------------------------------------------------------------
            
            print()
            
            for plan in plaene:
                print(f'QUELLE: {plan["quelle"]}')
                print(f'ZIEL:   {plan["ziel"]}')
            
            print()
            print(f"Geplante Umbenennungen: {len(plaene)}")
            print(f"Bisherige Fehler: {anzahl_fehler}")
            
            
            # ------------------------------------------------------------
            # Im Echtmodus bestätigen und die gespeicherten Pläne ausführen
            # ------------------------------------------------------------
            
            if not testmodus and plaene:
                print("ACHTUNG: Diese Dateien werden wirklich umbenannt.")
                print()
                antwort = input("Zum Fortfahren JA eingeben: ")
            
                if antwort.strip().casefold() != "ja":
                    print("Abgebrochen. Es wurde nichts umbenannt.")
                    sys.exit()
            
                for plan in plaene:
                    try:
                        eigene_datei = (
                            str(plan["quelle"].absolute()).casefold()
                            == str(plan["ziel"].absolute()).casefold()
                        )
            
                        if not eigene_datei and plan["ziel"].exists():
                            raise FileExistsError("Das geplante Ziel ist inzwischen belegt.")
            
                        plan["quelle"].rename(plan["ziel"])
                        print(f'UMBENANNT: {plan["quelle"]} -> {plan["ziel"]}')
                        anzahl_umbenannt += 1
                    except OSError as fehler:
                        print(f'FEHLER bei \'{plan["quelle"]}\': {fehler}')
                        anzahl_fehler += 1
            
            
            # ------------------------------------------------------------
            # Ergebnis zusammenfassen
            # ------------------------------------------------------------
            
            print()
            
            if testmodus:
                print(
                    "Es wurde nichts umbenannt. Für den Echtmodus _test aus dem "
                    "Starternamen entfernen."
                )
            else:
                print(f"Tatsächlich umbenannt: {anzahl_umbenannt}")
            
            print(f"Übersprungen: {anzahl_uebersprungen}")
            print(f"Fehler: {anzahl_fehler}")
            
            if anzahl_fehler > 0:
                sys.exit(1)
            

            So funktioniert die einfache Variante

            Arbeitsordner bestimmen

            basis_ordner = Path.cwd()

            Path.cwd() liefert den aktuellen Arbeitsordner. Die Starter-Batchdatei wechselt vorher mit cd /d "%~dp0" in ihren eigenen Ordner. Deshalb verarbeitet Python genau die Dateien, die gemeinsam mit dem Starter in diesem Ordner liegen.

            Dateien erfassen und sortieren

            dateien = sorted(
                (pfad for pfad in basis_ordner.iterdir() if pfad.is_file()),
                key=lambda pfad: str(pfad.absolute()).casefold(),
            )

            iterdir() liefert die direkt enthaltenen Elemente. is_file() übernimmt nur Dateien. sorted() sortiert sie vor der Planung nach ihrem vollständigen Pfad.

            Pläne als Dictionaries speichern

            plaene.append({"quelle": datei, "ziel": zielpfad})

            Jeder Plan ist ein Dictionary mit Quelle und Ziel. Die Datei wird an dieser Stelle noch nicht umbenannt. Erst nachdem alle Pläne erstellt und angezeigt wurden, kann der Echtmodus sie ausführen.

            Datei umbenennen

            plan["quelle"].rename(plan["ziel"])

            rename() benennt die Quelldatei in den gespeicherten Zielpfad um. Direkt davor wird noch einmal geprüft, ob ein fremdes Ziel inzwischen vorhanden ist.

            Starter-Batchdatei für Variante 1

            Dateiname für den Testlauf: 008_text_in_dateinamen_ersetzen_starter_batch_test.bat

            @echo off
            REM ============================================================
            REM TOPTORIALS OFFICE - Python Grundkurs
            REM Teil: 008 - Text in Dateinamen ersetzen
            REM Script: 008_text_in_dateinamen_ersetzen_starter_batch_test.bat
            REM Beschreibung:
            REM Startet das Python-Skript zum Ersetzen oder Entfernen
            REM von Text in Dateinamen im Ordner dieser Starter-Batchdatei.
            REM Autor: Chris
            REM YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
            REM Webseite: https://www.toptorials.com
            REM Version: Grundkurs 1.0
            REM Stand: 2026-09-01
            REM
            REM Hinweise:
            REM - Benoetigt Python 3, erreichbar ueber den Python Launcher py.
            REM - Starter und Python-Datei muessen im gleichen Ordner liegen.
            REM - Solange _test im Starternamen steht, wird --test uebergeben.
            REM - Im Testmodus werden keine Dateien umbenannt.
            REM - Fuer den Echtmodus _test aus dem Starternamen entfernen.
            REM - Das Python-Skript verlangt dann die Bestaetigung mit JA.
            REM - pause haelt das Fenster nach der Ausfuehrung offen.
            REM - Zuerst mit Testdateien arbeiten und wichtige Daten sichern.
            REM - Die Nutzung erfolgt auf eigene Verantwortung.
            REM ============================================================
            
            chcp 65001 >nul
            cd /d "%~dp0"
            
            echo("%~n0" | find /i "_test" >nul
            
            if not errorlevel 1 (
                py "008_text_in_dateinamen_ersetzen.py" --test
                REM Alternative, falls py nicht funktioniert:
                REM python "008_text_in_dateinamen_ersetzen.py" --test
            ) else (
                py "008_text_in_dateinamen_ersetzen.py"
                REM Alternative, falls py nicht funktioniert:
                REM python "008_text_in_dateinamen_ersetzen.py"
            )
            
            pause
            

            So funktioniert der Starter

            %~n0 liefert den eigenen Dateinamen ohne Endung. find /i "_test" sucht darin ohne Beachtung der Groß- und Kleinschreibung nach _test.

            Bei einem Treffer startet py das Python-Skript mit --test. Andernfalls wird dasselbe Skript ohne Testargument gestartet. pause hält das Fenster nach dem Python-Aufruf offen.

            Variante 2: Text über „Senden an“ ersetzen

            SendTo-Verknüpfung einrichten

            1. Erstelle eine Verknüpfung zur Starter-Batchdatei.
            2. Drücke Windows + R.
            3. Gib shell:sendto ein und bestätige mit Enter.
            4. Lege die Verknüpfung in diesem Ordner ab.

            Der tatsächliche Dateiname der ursprünglichen Starter-Batchdatei entscheidet über den Testmodus. Der Anzeigename der Verknüpfung ist dafür nicht maßgeblich.

            So wird die Variante angewendet

            Markiere im Windows-Explorer eine oder mehrere Dateien und Ordner. Öffne das Kontextmenü und wähle unter Senden an die angelegte Verknüpfung. Einzelne Dateien werden direkt aufgenommen. Bei einem Ordner werden nur dessen direkt enthaltene Dateien verarbeitet.

            Vollständiges Python-Skript

            Dateiname: 008_sendto_text_in_dateinamen_ersetzen.py

            # ============================================================
            # TOPTORIALS OFFICE - Python Grundkurs
            # Teil: 008 - Text in Dateinamen ersetzen
            # Script: 008_sendto_text_in_dateinamen_ersetzen.py
            # Beschreibung:
            # Ersetzt oder entfernt Text in den Dateinamen übergebener Dateien
            # sowie in den Dateinamen direkt enthaltener Dateien übergebener Ordner.
            # Die Ersetzung berücksichtigt auch die Dateiendung.
            # Autor: Chris
            # YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
            # Webseite: https://www.toptorials.com
            # Version: Grundkurs 1.0
            # Stand: 2026-09-01
            #
            # Hinweise:
            # - Benötigt Python 3.
            # - Dateien und Ordner werden über "Senden an" übergeben.
            # - Mit --test werden die geplanten Umbenennungen nur angezeigt.
            # - Ohne --test erfolgt die Ausführung nach Bestätigung mit JA.
            # - Ein leerer Ersatztext entfernt alle gefundenen Textstellen.
            # - Die Suche ignoriert Groß- und Kleinschreibung.
            # - Ordnernamen bleiben unverändert; keine rekursive Verarbeitung.
            # - .bat, .cmd, .ps1, .py und .log werden ausgeschlossen.
            # - Doppelt erfasste Dateipfade werden nur einmal verarbeitet.
            # - Alle Umbenennungen werden vor der Ausführung geplant.
            # - Namenskonflikte erhalten Zusätze wie _001, _002 usw.
            # - Zuerst mit Testdateien arbeiten und wichtige Daten sichern.
            # - Die Nutzung erfolgt auf eigene Verantwortung.
            # ============================================================
            
            from pathlib import Path
            import re
            import sys
            
            
            # ------------------------------------------------------------
            # Hilfsfunktion: Einen Pfad sprachunabhängig vergleichen
            # ------------------------------------------------------------
            
            def pfad_schluessel(pfad):
                return str(pfad.absolute()).casefold()
            
            
            # ------------------------------------------------------------
            # Hilfsfunktion: Einen freien Zielpfad ermitteln
            # ------------------------------------------------------------
            
            def get_freier_zielpfad(ordner, dateiname, quellpfad, reservierte_ziele):
                basis = Path(dateiname).stem
                endung = Path(dateiname).suffix
                zielname = dateiname
                nummer = 0
            
                while True:
                    zielpfad = ordner / zielname
                    vergleichs_ziel = pfad_schluessel(zielpfad)
            
                    eigene_datei = (
                        nummer == 0
                        and vergleichs_ziel == pfad_schluessel(quellpfad)
                    )
                    vorhanden = zielpfad.exists()
                    reserviert = vergleichs_ziel in reservierte_ziele
            
                    if (eigene_datei or not vorhanden) and not reserviert:
                        reservierte_ziele.add(vergleichs_ziel)
                        return zielpfad
            
                    nummer += 1
                    zielname = f"{basis}_{nummer:03d}{endung}"
            
            
            # ------------------------------------------------------------
            # Argumente und Testmodus auswerten
            # ------------------------------------------------------------
            
            argumente = sys.argv[1:]
            testmodus = "--test" in argumente
            pfad_argumente = []
            
            for argument in argumente:
                if argument != "--test":
                    pfad_argumente.append(argument)
            
            if not pfad_argumente:
                print("Bitte Dateien oder Ordner über 'Senden an' übergeben.")
                sys.exit(1)
            
            
            # ------------------------------------------------------------
            # Suchtext und Ersatztext abfragen
            # ------------------------------------------------------------
            
            print()
            print("Text in Dateinamen ersetzen")
            print(
                "Ersetzt wird auch in der Dateiendung. "
                "Ein leerer Ersatztext entfernt den Suchtext."
            )
            print()
            print(f"Testmodus: {'JA' if testmodus else 'NEIN'}")
            print()
            
            alter_text = input("Alter Text / Suchtext: ")
            
            if alter_text == "":
                print("Kein Suchtext eingegeben. Abgebrochen.")
                sys.exit()
            
            neuer_text = input("Neuer Text / Ersatztext: ")
            print()
            
            ungueltige_zeichen = '<>:"/\\|?*'
            
            if any(zeichen in neuer_text for zeichen in ungueltige_zeichen) or any(
                ord(zeichen) < 32 for zeichen in neuer_text
            ):
                print("Der Ersatztext enthält unzulässige Zeichen. Es wurde nichts geändert.")
                sys.exit(1)
            
            # re.escape() behandelt den Suchtext wörtlich.
            # Die lambda-Funktion behandelt auch den Ersatztext wörtlich.
            suchmuster = re.compile(re.escape(alter_text), re.IGNORECASE)
            ausgeschlossene_endungen = (".bat", ".cmd", ".ps1", ".py", ".log")
            
            plaene = []
            dateien = []
            bereits_erfasste_dateien = set()
            reservierte_ziele = set()
            anzahl_umbenannt = 0
            anzahl_uebersprungen = 0
            anzahl_fehler = 0
            
            
            # ------------------------------------------------------------
            # Übergebene Dateien und direkte Ordnerinhalte sammeln
            # ------------------------------------------------------------
            
            for pfad_text in pfad_argumente:
                element = Path(pfad_text)
            
                try:
                    if not element.exists():
                        print(f"FEHLER bei '{pfad_text}': Datei oder Ordner wurde nicht gefunden")
                        anzahl_fehler += 1
                        continue
            
                    element = element.resolve()
            
                    if element.is_dir():
                        for pfad in element.iterdir():
                            if pfad.is_file():
                                dateien.append(pfad)
                    elif element.is_file():
                        dateien.append(element)
                    else:
                        print(f"FEHLER bei '{pfad_text}': Keine Datei und kein Ordner")
                        anzahl_fehler += 1
                except OSError as fehler:
                    print(f"FEHLER bei '{pfad_text}': {fehler}")
                    anzahl_fehler += 1
            
            
            # ------------------------------------------------------------
            # Umbenennungen planen, noch keine Datei verändern
            # ------------------------------------------------------------
            
            for datei in sorted(dateien, key=lambda pfad: pfad_schluessel(pfad)):
                vergleichs_quelle = pfad_schluessel(datei)
            
                if vergleichs_quelle in bereits_erfasste_dateien:
                    continue
            
                bereits_erfasste_dateien.add(vergleichs_quelle)
            
                if datei.suffix.casefold() in ausgeschlossene_endungen:
                    print(f"ÜBERSPRUNGEN: {datei.name} - ausgeschlossene Endung")
                    anzahl_uebersprungen += 1
                    continue
            
                neuer_name = suchmuster.sub(lambda _: neuer_text, datei.name)
                neue_basis = suchmuster.sub(lambda _: neuer_text, datei.stem)
            
                if neue_basis == "":
                    neuer_name = "Unbenannt" + datei.suffix
            
                if neuer_name == datei.name:
                    print(f"ÜBERSPRUNGEN: {datei.name} - keine Änderung")
                    anzahl_uebersprungen += 1
                    continue
            
                if not neuer_name or neuer_name.isspace() or neuer_name.endswith((".", " ")):
                    print(f"FEHLER: Ungültiger Zielname für {datei.name}")
                    anzahl_fehler += 1
                    continue
            
                try:
                    zielpfad = get_freier_zielpfad(
                        datei.parent,
                        neuer_name,
                        datei,
                        reservierte_ziele,
                    )
                    plaene.append({"quelle": datei, "ziel": zielpfad})
                except OSError as fehler:
                    print(f"FEHLER beim Planen von '{datei}': {fehler}")
                    anzahl_fehler += 1
            
            
            # ------------------------------------------------------------
            # Vorschau anzeigen - auch vor einer echten Ausführung
            # ------------------------------------------------------------
            
            print()
            
            for plan in plaene:
                print(f'QUELLE: {plan["quelle"]}')
                print(f'ZIEL:   {plan["ziel"]}')
            
            print()
            print(f"Geplante Umbenennungen: {len(plaene)}")
            print(f"Bisherige Fehler: {anzahl_fehler}")
            
            
            # ------------------------------------------------------------
            # Im Echtmodus bestätigen und die gespeicherten Pläne ausführen
            # ------------------------------------------------------------
            
            if not testmodus and plaene:
                print("ACHTUNG: Diese Dateien werden wirklich umbenannt.")
                print()
                antwort = input("Zum Fortfahren JA eingeben: ")
            
                if antwort.strip().casefold() != "ja":
                    print("Abgebrochen. Es wurde nichts umbenannt.")
                    sys.exit()
            
                for plan in plaene:
                    try:
                        eigene_datei = (
                            pfad_schluessel(plan["quelle"])
                            == pfad_schluessel(plan["ziel"])
                        )
            
                        if not eigene_datei and plan["ziel"].exists():
                            raise FileExistsError("Das geplante Ziel ist inzwischen belegt.")
            
                        plan["quelle"].rename(plan["ziel"])
                        print(f'UMBENANNT: {plan["quelle"]} -> {plan["ziel"]}')
                        anzahl_umbenannt += 1
                    except OSError as fehler:
                        print(f'FEHLER bei \'{plan["quelle"]}\': {fehler}')
                        anzahl_fehler += 1
            
            
            # ------------------------------------------------------------
            # Ergebnis zusammenfassen
            # ------------------------------------------------------------
            
            print()
            
            if testmodus:
                print(
                    "Es wurde nichts umbenannt. Für den Echtmodus _test aus dem "
                    "Starternamen entfernen."
                )
            else:
                print(f"Tatsächlich umbenannt: {anzahl_umbenannt}")
            
            print(f"Übersprungen: {anzahl_uebersprungen}")
            print(f"Fehler: {anzahl_fehler}")
            
            if anzahl_fehler > 0:
                sys.exit(1)
            

            So funktioniert die SendTo-Variante

            Argumente und Testmodus trennen

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

            sys.argv enthält die beim Start übergebenen Argumente. Das Element mit Index 0 ist der Name des Python-Skripts. Der Ausschnitt [1:] übernimmt deshalb nur die nachfolgenden Argumente.

            In einer Schleife wird --test von den eigentlichen Datei- und Ordnerpfaden getrennt. Ohne mindestens einen Pfad zeigt das Skript einen Hinweis an und beendet sich.

            Dateien und Ordner unterscheiden

            if element.is_dir():
                for pfad in element.iterdir():
                    if pfad.is_file():
                        dateien.append(pfad)
            elif element.is_file():
                dateien.append(element)

            is_dir() erkennt einen Ordner. Dessen direkte Dateien werden mit iterdir() gesammelt. is_file() erkennt eine einzeln übergebene Datei.

            Doppelte Dateien verhindern

            vergleichs_quelle = pfad_schluessel(datei)
            
            if vergleichs_quelle in bereits_erfasste_dateien:
                continue
            
            bereits_erfasste_dateien.add(vergleichs_quelle)

            Eine Datei kann einzeln und gleichzeitig über ihren Ordner übergeben worden sein. Das Set bereits_erfasste_dateien sorgt dafür, dass ihr vollständiger Pfad trotzdem nur einmal verarbeitet wird.

            Dieses Set schützt die Quelldateien vor doppelter Verarbeitung. Das zweite Set reservierte_ziele verhindert dagegen doppelte geplante Zielpfade.

            Starter-Batchdatei für Variante 2

            Dateiname für den Testlauf: 008_sendto_text_in_dateinamen_ersetzen_starter_batch_test.bat

            @echo off
            REM ============================================================
            REM TOPTORIALS OFFICE - Python Grundkurs
            REM Teil: 008 - Text in Dateinamen ersetzen
            REM Script: 008_sendto_text_in_dateinamen_ersetzen_starter_batch_test.bat
            REM Beschreibung:
            REM Startet die SendTo-Variante zum Ersetzen oder Entfernen von
            REM Text in Dateinamen und reicht die uebergebenen Pfade weiter.
            REM Autor: Chris
            REM YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
            REM Webseite: https://www.toptorials.com
            REM Version: Grundkurs 1.0
            REM Stand: 2026-09-01
            REM
            REM Hinweise:
            REM - Benoetigt Python 3, erreichbar ueber den Python Launcher py.
            REM - Starter und Python-Datei muessen im gleichen Ordner liegen.
            REM - Eine Verknuepfung zu diesem Starter in "Senden an" ablegen.
            REM - Dateien und Ordner im Explorer markieren und dorthin senden.
            REM - Solange _test im Starternamen steht, wird --test uebergeben.
            REM - Der Anzeigename der Verknuepfung steuert den Testmodus nicht.
            REM - Fuer den Echtmodus _test aus dem Starternamen entfernen.
            REM - Die SendTo-Verknuepfung danach gegebenenfalls aktualisieren.
            REM - Das Python-Skript verlangt dann die Bestaetigung mit JA.
            REM - pause haelt das Fenster nach der Ausfuehrung offen.
            REM - Zuerst mit Testdateien arbeiten und wichtige Daten sichern.
            REM - Die Nutzung erfolgt auf eigene Verantwortung.
            REM ============================================================
            
            chcp 65001 >nul
            cd /d "%~dp0"
            
            echo("%~n0" | find /i "_test" >nul
            
            if not errorlevel 1 (
                py "008_sendto_text_in_dateinamen_ersetzen.py" --test %*
                REM Alternative, falls py nicht funktioniert:
                REM python "008_sendto_text_in_dateinamen_ersetzen.py" --test %*
            ) else (
                py "008_sendto_text_in_dateinamen_ersetzen.py" %*
                REM Alternative, falls py nicht funktioniert:
                REM python "008_sendto_text_in_dateinamen_ersetzen.py" %*
            )
            
            pause
            

            Der Ausdruck %* reicht alle an die Batchdatei übergebenen Argumente an Python weiter. Das sind die im Explorer ausgewählten Datei- und Ordnerpfade. Im Testzweig wird zusätzlich --test übergeben.

            Typische Meldungen

            Vorschau einer geplanten Umbenennung

            QUELLE: C:\Test\MeinBeispiel.txt
            ZIEL:   C:\Test\Beispiel_001.txt

            Datei wurde umbenannt

            UMBENANNT: C:\Test\MeinBeispiel.txt -> C:\Test\Beispiel_001.txt

            Dateiname bleibt unverändert

            ÜBERSPRUNGEN: Beispiel.txt - keine Änderung

            Dateiendung ist ausgeschlossen

            ÜBERSPRUNGEN: Hilfsskript.py - ausgeschlossene Endung

            Leerer Suchtext

            Kein Suchtext eingegeben. Abgebrochen.

            Unzulässige Zeichen im Ersatztext

            Der Ersatztext enthält unzulässige Zeichen. Es wurde nichts geändert.

            Typische Fehler und mögliche Ursachen

            Der Befehl py wurde nicht gefunden

            Prüfe mit py --version, ob der Python Launcher verfügbar ist. Falls Python nur über python gestartet werden kann, stehen die entsprechenden alternativen Zeilen bereits als Kommentare in den Starter-Batchdateien.

            Das Python-Skript wird nicht gefunden

            Prüfe, ob Starter und Python-Datei im gleichen Ordner liegen und ob der Dateiname im Aufruf exakt stimmt. Zusätze wie (1) oder (2), die beim mehrfachen Herunterladen entstehen können, gehören nicht zu den vorgesehenen Namen.

            Der Starter zeigt Testmodus: NEIN

            Im tatsächlichen Namen der Starter-Batchdatei fehlt _test. Beende den Durchlauf und ergänze den Zusatz. Eine Kommentarzeile oder der Anzeigename der SendTo-Verknüpfung aktiviert den Testmodus nicht.

            Nach dem Entfernen von _001 erscheint _002

            Der Name ohne Nummer ist bereits belegt. Die Quelldatei mit _001 existiert während der Planung ebenfalls noch. Deshalb wird mit _002 der nächste freie Zielname gesucht.

            Es werden weniger Dateien bearbeitet als erwartet

            Prüfe die ausgeschlossenen Endungen und die Lage der Dateien. Unterordner werden nicht rekursiv durchsucht. Namen ohne Treffer werden als keine Änderung übersprungen. Doppelt erfasste SendTo-Dateien werden nur einmal berücksichtigt.

            Ein Zielname ist ungültig

            Der Ersatztext darf unter Windows unter anderem keine Zeichen wie \, /, :, * oder ? enthalten. Auch ein vollständig leerer Zielname sowie ein abschließender Punkt oder ein abschließendes Leerzeichen werden zurückgewiesen.

            Diese Grundkurs-Version prüft nicht sämtliche Windows-Namensregeln im Voraus. Reservierte Gerätenamen oder zu lange Pfade können deshalb erst bei der tatsächlichen Umbenennung einen Fehler auslösen.

            Eine Datei kann nicht umbenannt werden

            Mögliche Ursachen sind fehlende Rechte, eine Dateisperre durch ein anderes Programm oder ein Ziel, das nach der Planung neu angelegt wurde. Das Skript meldet den Fehler und arbeitet anschließend die übrigen Pläne weiter ab.

            Wichtige Python-Begriffe aus diesem Tutorial

            Path.cwd()
            Liefert den aktuellen Arbeitsordner als Path-Objekt.
            Path.iterdir()
            Liefert die direkt in einem Ordner enthaltenen Elemente.
            is_file() und is_dir()
            Prüfen, ob ein Pfad eine Datei oder ein Ordner ist.
            name, stem und suffix
            Liefern den vollständigen Dateinamen, den Basisnamen ohne letzte Endung und die letzte Endung einschließlich Punkt.
            re.escape()
            Maskiert Zeichen im Suchtext, damit sie im regulären Ausdruck wörtlich gesucht werden.
            re.IGNORECASE
            Aktiviert eine Suche ohne Beachtung der Groß- und Kleinschreibung.
            sub()
            Ersetzt alle Treffer des vorbereiteten Suchmusters.
            lambda
            Erstellt hier eine kleine namenlose Funktion, die den Ersatztext für jeden Treffer zurückgibt.
            casefold()
            Erzeugt eine für sprachunabhängige Vergleiche geeignete Schreibweise, ohne den ursprünglichen Pfad umzubenennen.
            set()
            Erstellt eine Sammlung eindeutiger Werte. Sie dient hier zur Deduplizierung und Zielreservierung.
            list.append()
            Fügt einer Liste einen neuen Eintrag hinzu.
            Dictionary
            Speichert zusammengehörige Werte mit Schlüsseln, hier quelle und ziel.
            sorted()
            Sortiert die Dateipfade vor der Planung.
            f"{nummer:03d}"
            Formatiert die Nummer mit mindestens drei Ziffern und führenden Nullen.
            exists()
            Prüft, ob ein Zielpfad bereits vorhanden ist.
            rename()
            Führt die eigentliche Umbenennung aus.
            try und except OSError
            Fangen Dateisystemfehler kontrolliert ab.
            sys.argv[1:]
            Übernimmt die Argumente nach dem Namen des Python-Skripts.
            continue
            Beendet den aktuellen Schleifendurchlauf und fährt mit dem nächsten Element fort.

            Wichtige Batch-Begriffe aus diesem Tutorial

            %~dp0
            Liefert Laufwerk und Ordner der ausgeführten Starter-Batchdatei.
            cd /d
            Wechselt in diesen Ordner und bei Bedarf auch auf das passende Laufwerk.
            %~n0
            Liefert den Namen der Batchdatei ohne Pfad und Dateiendung.
            find /i
            Sucht ohne Beachtung der Groß- und Kleinschreibung nach _test.
            if not errorlevel 1
            Prüft hier, ob find den Text gefunden hat.
            %*
            Reicht alle an den SendTo-Starter übergebenen Pfade an Python weiter.
            pause
            Wartet nach dem Skriptlauf auf einen Tastendruck.

            Was haben wir in diesem Teil gelernt?

            Mit input() fragen wir Suchtext und Ersatztext ab. re.escape() sorgt dafür, dass der Suchtext wörtlich behandelt wird, während re.IGNORECASE die Suche unabhängig von Groß- und Kleinschreibung macht.

            sub() ersetzt alle Treffer. Eine lambda-Funktion gibt dabei den Ersatztext wörtlich zurück. Ein leerer Ersatztext entfernt den gefundenen Text. Wird der Basisname vollständig gelöscht, verwendet das Skript Unbenannt.

            get_freier_zielpfad() sucht bei Namenskonflikten Ziele mit _001, _002 und weiteren Nummern. Ein Set reserviert bereits geplante Zielpfade.

            Die einfache Variante arbeitet im Ordner der Starter-Batchdatei. Die SendTo-Variante übernimmt mehrere Dateien und Ordner aus dem Windows-Explorer und verhindert die doppelte Verarbeitung derselben Datei.

            Beide Varianten verarbeiten nur direkt enthaltene Dateien und lassen die festgelegten Skript- und Protokollendungen aus. Im Testmodus werden alle Pläne nur angezeigt. Im Echtmodus führt rename() die gespeicherten Umbenennungen erst nach der Bestätigung mit JA aus.

            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 Teil 008: Text in Dateinamen ersetzen
            • PowerShell 7 Grundkurs Teil 008: Text in Dateinamen ersetzen
            • Batch Grundkurs 008: Text in Dateinamen suchen und ersetzen
            • Python Grundkurs Teil 007: Zeitstempel hinzufügen und entfernen
            • PowerShell 7 Grundkurs Teil 007: Zeitstempel hinzufügen und entfernen

            Neue Kommentare

            • Chris zu Zeilen, Spalten, Fenster fixieren (FreeOffice PlanMaker)
            • Herbert Krüger zu Zeilen, Spalten, Fenster fixieren (FreeOffice PlanMaker)
            • Chris zu Tutorial Wunsch Liste
            • Rupert zu Tutorial Wunsch Liste
            • Axel zu Datumsformat anpassen (LibreOffice Calc)
            • Klaus zu Dynamischen Monatskalender erstellen + Download (LibreOffice Calc)

            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