Dateien umbenennen - Konsole oder Software

DHC schrieb:
"Das ist das Haus vom Nikolaus - 2024-09-20.jpg"
Das wäre dann so.
Nikolaus Haus.png
Ergänzung ()

DHC schrieb:
Sowas geht wahrscheinlich nur mit entsprechenden Skripten.
Vermute ich mal.
Oder jede Datei händisch umbenennen. Mit Scripten kenne ich mich auch nicht aus.
 
Ponderosa schrieb:
Mit Scripten kenne ich mich auch nicht aus
Eben. Damit kenne ich mich eben auch nicht aus.
Ich denke, das man sowas mit Batch-Skript in der Eingabeaufforderung oder PowerShell realisieren kann.
Evtl. gibt es auch Programme, die Skripte unterstützen. Theoretischer Vorteil die UnDo-Funktion, sprich rückgängig machen.

Deshalb frage ich ja hier, ob jemand Erfahrung mit massenweiser, spezieller, Umbenennung hat.
 
Hier mal meine Lösung mithilfe ChatGPT gebastelt. Hatte gerade Langeweile;)
Den Code als .ps1-Datei speichern.
Den Pfad deiner Dateien "-Path "D:\" entsprechend anpassen.

Code:
Get-ChildItem -Path "D:\" -File | ForEach-Object {
    # Extrahiere den Dateinamen und die Erweiterung
    $dateiName = $_.BaseName
    $erweiterung = $_.Extension

    # Überprüfe, ob der Dateiname das Muster "dd.mm.yyyy" enthält
    if ($dateiName -match '\b(\d{2})\.(\d{2})\.(\d{4})\b') {
        # Extrahiere Tag, Monat und Jahr aus dem Dateinamen
        $tag = $matches[1]
        $monat = $matches[2]
        $jahr = $matches[3]

        # Ersetze den Datumsbereich mit dem neuen Format "yyyy-mm-dd"
        $neuerDateiName = $dateiName -replace '\b(\d{2})\.(\d{2})\.(\d{4})\b', "$jahr-$monat-$tag"

        # Ersetze alle nicht-alphanumerischen Zeichen vor dem Datum mit einem Bindestrich
        $neuerDateiName = $neuerDateiName -replace '[^a-zA-Z0-9]+(?=\d{4}-\d{2}-\d{2})', ' - '

        # Datei umbenennen
        Rename-Item $_ -NewName "$neuerDateiName$erweiterung"

        # Bestätigung ausgeben: Alter und neuer Dateiname
        Write-Host "Umbenannt: '$($_.Name)' zu '$neuerDateiName$erweiterung'"
    }
}

umbenennen.png
 
  • Gefällt mir
Reaktionen: Keylan
Jetzt müsste man noch sicherstellen, das die resultirenden Dateinamen Eindeutig bleiben, damit das ganze nicht auf die Nase fällt, aber mit sowas wird es natürlich gleich deutlich Komplexer.
 
@Ponderosa
Das sieht vom Prinzip her nicht schlecht aus.
Danke für deine Unterstützung.
Zum Glück ist Wochenende und Langweile hast du auch noch. Und das bei dem schönen Wetter aktuell.
Es fehlt aber noch die Prüfung, ob das Datumsformat schon korrekt ist, dann nicht umbenennen.
Oder interpretiere ich das Skript falsch?

Edit:
OK. Wird ja geprüft. (IF .....)
Alles gut.


@Keylan
Das ist ein guter Einwand.
Wobei das bei mir zu 99,99 % nicht der Fall sein sollte.
Sowas müsste man dann natürlich irgendwie abfangen.
Wie das auch immer aussieht.
Ergänzung ()

Kann man, zum Testen die Ausgabe
Code:
        # Bestätigung ausgeben: Alter und neuer Dateiname
        Write-Host "Umbenannt: '$($_.Name)' zu '$neuerDateiName$erweiterung'"
in eine Datei umleiten?

Ich würde dann erst mal
Code:
        # Datei umbenennen
        Rename-Item $_ -NewName "$neuerDateiName$erweiterung"
entfernen, um die korrekte Funktion in der Ausgabe-Datei zu überprüfen.
 
  • Gefällt mir
Reaktionen: Ponderosa
DHC schrieb:
Zum Glück ist Wochenende und Langweile hast du auch noch.
Und Rentner, ach nein allein lebender Privatier bin ich auch noch.
Hab so alle Zeit der Welt. ⌛
 
Keylan schrieb:
Jetzt müsste man noch sicherstellen, das die resultirenden Dateinamen Eindeutig bleiben, damit das ganze nicht auf die Nase fällt, aber mit sowas wird es natürlich gleich deutlich Komplexer.
Das geht auch:

Code:
Get-ChildItem -Path "D:\" -File | ForEach-Object {
    # Extrahiere den Dateinamen und die Erweiterung
    $dateiName = $_.BaseName
    $erweiterung = $_.Extension

    # Überprüfe, ob der Dateiname das Muster "dd.mm.yyyy" enthält
    if ($dateiName -match '\b(\d{2})\.(\d{2})\.(\d{4})\b') {
        # Extrahiere Tag, Monat und Jahr aus dem Dateinamen
        $tag = $matches[1]
        $monat = $matches[2]
        $jahr = $matches[3]

        # Ersetze den Datumsbereich mit dem neuen Format "yyyy-mm-dd"
        $neuerDateiName = $dateiName -replace '\b(\d{2})\.(\d{2})\.(\d{4})\b', "$jahr-$monat-$tag"

        # Ersetze alle nicht-alphanumerischen Zeichen vor dem Datum mit einem Bindestrich
        $neuerDateiName = $neuerDateiName -replace '[^a-zA-Z0-9]+(?=\d{4}-\d{2}-\d{2})', ' - '

        # Setze den vollständigen neuen Dateinamen (inklusive Erweiterung)
        $vollstaendigerNeuerDateiName = "$neuerDateiName$erweiterung"
        $counter = 1

        # Überprüfe, ob die Datei mit dem neuen Namen bereits existiert
        while (Test-Path -Path (Join-Path "D:\" $vollstaendigerNeuerDateiName)) {
            # Füge eine laufende Nummer hinzu, falls die Datei bereits existiert
            $vollstaendigerNeuerDateiName = "$neuerDateiName-$counter$erweiterung"
            $counter++
        }

        # Datei umbenennen
        Rename-Item $_ -NewName $vollstaendigerNeuerDateiName

        # Bestätigung ausgeben: Alter und neuer Dateiname
        Write-Host "Umbenannt: '$($_.Name)' zu '$vollstaendigerNeuerDateiName'"
    }
}
 
Noch ne Frage.
Werden in dem Skript auch alle Unterordner im Pfad
Code:
Get-ChildItem -Path "D:\" -File
berücksichtigt?
 
Wäre es nicht sinnvoller statt auf das Dateisystem zuzugreifen, wie hier
Code:
        # Überprüfe, ob die Datei mit dem neuen Namen bereits existiert
        while (Test-Path -Path (Join-Path "D:\" $vollstaendigerNeuerDateiName)) {
            # Füge eine laufende Nummer hinzu, falls die Datei bereits existiert
            $vollstaendigerNeuerDateiName = "$neuerDateiName-$counter$erweiterung"
            $counter++
        }
Auf eine Ausgabedatei zuzugreifen. Weil schnellerer Zugriff, als auf Dateisystemebene.
Ergänzung ()

Sprich erst mal eine Ausgabe-Datei erstellen, so ne Art Preprozess, der die Vorarbeit macht.
Die man dann auch erst mal kontrollieren könnte, bevor dann die eigentliche Arbeit gemacht wird.
Und dann gemäß der Ausgabe-Datei dann im Nachgang umbenennen.

Oder habe ich einen Denkfehler.
 
DHC schrieb:
Noch ne Frage.
Werden in dem Skript auch alle Unterordner im Pfad
Code:
Get-ChildItem -Path "D:\" -File
berücksichtigt?
Jetzt mit Unterordnern:

Code:
Get-ChildItem -Path "D:\" -File -Recurse | ForEach-Object {
    # Extrahiere den Dateinamen und die Erweiterung
    $dateiName = $_.BaseName
    $erweiterung = $_.Extension

    # Überprüfe, ob der Dateiname das Muster "dd.mm.yyyy" enthält
    if ($dateiName -match '\b(\d{2})\.(\d{2})\.(\d{4})\b') {
        # Extrahiere Tag, Monat und Jahr aus dem Dateinamen
        $tag = $matches[1]
        $monat = $matches[2]
        $jahr = $matches[3]

        # Ersetze den Datumsbereich mit dem neuen Format "yyyy-mm-dd"
        $neuerDateiName = $dateiName -replace '\b(\d{2})\.(\d{2})\.(\d{4})\b', "$jahr-$monat-$tag"

        # Ersetze alle nicht-alphanumerischen Zeichen vor dem Datum mit einem Bindestrich
        $neuerDateiName = $neuerDateiName -replace '[^a-zA-Z0-9]+(?=\d{4}-\d{2}-\d{2})', ' - '

        # Bestimme das Verzeichnis, in dem die Datei sich befindet
        $verzeichnis = $_.DirectoryName

        # Setze den vollständigen neuen Dateinamen (inklusive Erweiterung)
        $vollstaendigerNeuerDateiName = "$neuerDateiName$erweiterung"
        $counter = 1

        # Überprüfe, ob die Datei mit dem neuen Namen bereits existiert
        while (Test-Path -Path (Join-Path $verzeichnis $vollstaendigerNeuerDateiName)) {
            # Füge eine laufende Nummer hinzu, falls die Datei bereits existiert
            $vollstaendigerNeuerDateiName = "$neuerDateiName-$counter$erweiterung"
            $counter++
        }

        # Vollständiger Pfad der neuen Datei
        $neuerVollerPfad = Join-Path $verzeichnis $vollstaendigerNeuerDateiName

        # Datei umbenennen
        Rename-Item $_.FullName -NewName $neuerVollerPfad

        # Bestätigung ausgeben: Alter und neuer Dateiname
        Write-Host "Umbenannt: '$($_.FullName)' zu '$neuerVollerPfad'"
    }
}
 
@Ponderosa
@JennyCB
Ihr seid einfach spitze.
Vielen Dank für eure Unterstützung.

Wenn das nun noch alles in zwei Schritten gehen würde, wäre ich wunschlos glücklich.

Sprich.
  • Erst Analysieren und Ausgabedatei generieren
  • Im zweiten Schritt, nach manueller Kontrolle, gemäß Ausgabedatei umbenennen
 
DHC schrieb:
Ich kenne mich mit ChatGPT nicht aus und bin da auch nirgendswo angemeldet. Ist, glaube ich, auch Pflicht.
Kannst auch bei duckduckgo GPT4-Mini ohne Registrierung nutzen.
 
@pseudopseudonym Habe ich noch nie genutzt.
Ich wüsste ehrlich gesagt auch nicht, wie ich das alles formulieren sollte, damit da was gescheites dabei heraus kommt.
 
F1database schrieb:
ich benutze für sowas den Total Commander und dabei dann dass "Multi-Rename Tool"
Ist auch meine Empfehlung. Der bietet unzählige Optionen, auch reguläre Ausdrücke. Und man bekommt vorher angezeigt was passiert.
 
DHC schrieb:
Sprich.
  • Erst Analysieren und Ausgabedatei generieren
  • Im zweiten Schritt, nach manueller Kontrolle, gemäß Ausgabedatei umbenennen
Das geht auch als Vorschau:

Code:
Get-ChildItem -Path "D:\" -File -Recurse | ForEach-Object {
    # Extrahiere den Dateinamen und die Erweiterung
    $dateiName = $_.BaseName
    $erweiterung = $_.Extension

    # Überprüfe, ob der Dateiname das Muster "dd.mm.yyyy" enthält
    if ($dateiName -match '\b(\d{2})\.(\d{2})\.(\d{4})\b') {
        # Extrahiere Tag, Monat und Jahr aus dem Dateinamen
        $tag = $matches[1]
        $monat = $matches[2]
        $jahr = $matches[3]

        # Ersetze den Datumsbereich mit dem neuen Format "yyyy-mm-dd"
        $neuerDateiName = $dateiName -replace '\b(\d{2})\.(\d{2})\.(\d{4})\b', "$jahr-$monat-$tag"

        # Ersetze alle nicht-alphanumerischen Zeichen vor dem Datum mit einem Bindestrich
        $neuerDateiName = $neuerDateiName -replace '[^a-zA-Z0-9]+(?=\d{4}-\d{2}-\d{2})', ' - '

        # Bestimme das Verzeichnis, in dem die Datei sich befindet
        $verzeichnis = $_.DirectoryName

        # Setze den vollständigen neuen Dateinamen (inklusive Erweiterung)
        $vollstaendigerNeuerDateiName = "$neuerDateiName$erweiterung"
        $counter = 1

        # Überprüfe, ob die Datei mit dem neuen Namen bereits existiert
        while (Test-Path -Path (Join-Path $verzeichnis $vollstaendigerNeuerDateiName)) {
            # Füge eine laufende Nummer hinzu, falls die Datei bereits existiert
            $vollstaendigerNeuerDateiName = "$neuerDateiName-$counter$erweiterung"
            $counter++
        }

        # Vollständiger Pfad der neuen Datei
        $neuerVollerPfad = Join-Path $verzeichnis $vollstaendigerNeuerDateiName

        # Nur die Vorschau anzeigen, ohne Umbenennung
        Write-Host "Vorschau: '$($_.FullName)' wuerde zu '$neuerVollerPfad' umbenannt werden."
    }
}
 
Zuletzt bearbeitet:
DHC schrieb:
Erst Analysieren und Ausgabedatei generieren
Bei Freecommander wäre das.
1) Analysieren = Vorschau
wenn alles stimmt, dann umbenennen
2) Umbenennen = Ausgabe generieren
 

Anhänge

  • Nikolaus Haus.png
    Nikolaus Haus.png
    88,5 KB · Aufrufe: 32
Ponderosa schrieb:
Bei Freecommander wäre das.
In dem Beispiel ist das Umbenennen aber statisch ohne Prüfung des Datumformates.

Da ist mir die Lösung mit dem Skript schon lieber.
Ergänzung ()

JennyCB schrieb:
Das geht auch als Vorschau:
Mit Vorschau meinte ich, das in Skript 1 erst nur eine Ausgabedatei (txt) generiert wird, dass entweder die Dateinamen vor und nach der Umbenennung beinhaltet.
Z. B.:
Code:
"C:\Ordner\Dateiname, 03.01.1985"    "Dateiname - 1985-01-03"
"C:\Ordner\Dateiname; 13.02.1995"    "Dateiname - 1995-02-13"
"C:\Ordner\Dateiname) 23.11.1998"    "Dateiname - 1998-11-23"
Oder gleich mit dem passenden Befehl mit dabei:
Code:
rename "C:\Ordner\Dateiname, 03.01.1985" "Dateiname - 1985-01-03"
rename "C:\Ordner\Dateiname; 13.02.1995" "Dateiname - 1995-02-13"
rename "C:\Ordner\Dateiname) 23.11.1998" "Dateiname - 1998-11-23"
Dann kann ich alles nochmal durchgehen und schauen, ob es passt, bzw. ggf. noch korrigieren.
Und im Skript 2 wird dann anhand der Ausgabedatei alles darin enthaltene umbenannt.
 
Zuletzt bearbeitet:
Ich habe mal das Skript in der PowerShell als Vorschau getestet.

Aber das war eine Geburt, bis das funktionierte.
Bei mir ist das wohl gesperrt.
Restricted / Undefined
Ich musste mir erst mal die Berechtigung erteilen.
Nach dem testen habe ich die wieder entfernt.
Es wird wohl einen Grund geben, warum das deaktiviert ist.

Ändern der Ausführungsrichtlinie
PowerShell:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Entfernen der Ausführungsrichtlinie
PowerShell:
Set-ExecutionPolicy -ExecutionPolicy Undefined -Scope CurrentUser
Ergänzung ()

Ich danke hier noch mal ausdrücklich @Ponderosa und @JennyCB.
Ich habt mir das Umbenennen erheblich erleichtert.

Schon interessant, was da für Hieroglyphen in dem Code sind.
Z. B.:
PowerShell:
'[^a-zA-Z0-9]+(?=\d{4}-\d{2}-\d{2})', ' - '
Wer versteht denn sowas?
 
  • Gefällt mir
Reaktionen: Ponderosa
Zurück
Oben