alexander01
Goto Top

Umbenennen von Dateinamen mit PowerShell (2)

Hallo, ihr habt mir gestern und schon im Jahr 2020 sehr geholfen. Ich muß viele Bild-Dateien in ein einheitliches Format überführen. jedoch gibt es unterschiedliche Ausgangssituationen. Meine Bitte um Hilfe bei einem anderen zweiten PowerShell-Script habt ihr gehört, Eure Lösungen haben den Sachverhalt vorgestern erfolgreich beenden können. Das Script funktionierte gut, ich habe mehrere hundert Dateien umformatiert. Nochmals vielen Dank an Alle !
Kann mir jemand bei einem ähnlichen Sachverhalt nochmal behilflich sein?

Das jetzige Script funktioniert gut und fehlerfrei:

# Pfad bitte anpassen
$root = 'k:\quelle'  
$batch = 0
# Abfrage aller Ordner der ersten Ebene im Root-Ordner 
ls $root -Directory | %{
    # alle 5 Ordner anhalten und fragen
    if ($batch % 5 -eq 0){
        Read-Host "`nEnter drücken zum fortfahren für den nächsten Batch an Ordnern"  
    }
    # Unterordner abfragen deren Namen dem Datumsmuster entspricht
    ls $_.FullName -Directory | ?{$_.Name -match '(\d{1,2})\.(\d{1,2})\.(\d{4})'} | %{  
        # Datum neu formatieren und an Variable übergeben 
        $d = [datetime]::ParseExact($matches,'M.d.yyyy',[cultureinfo]::InvariantCulture).toString('yyyy-MM-dd')  
        # neuen Ordner eine Ebene höher erstellen
        $newfolder = (Join-Path $_.Parent.FullName $d)
        md $newfolder -Force | out-null
        # Zähler initialisieren
        $cnt = 1
        # Alle *.tif Dateien des Unterordner "Images" in den neuen Ordner unter neuem Namen verschieben 
        ls "$($_.FullName)\Images" -File -Filter *.tif | %{  
            move-item $_.Fullname -Destination "$newfolder\${d}-Image$cnt$($_.Extension)" -Verbose  
            $cnt++
        }
        # alten Ordner rekursiv löschen
        del $_.FullName -Force -Recurse
    }
    # evt. Steuerdateien löschen
    ls $_.Fullname -File | del -Force

    $batch++
    }
    pause

Ausgangslage:
Ordner (Zahl)
Ordner (dd.mm.yyyy.hh.mm.ss)
Ordner "images"
Dateien (dd.mm.yyyy.hh.mm.ss_[zähler])

Ergebnis:
Ordner (Zahl)
Ordner (yyyy-mm-dd)
Dateien (yyyy-mm-dd-Image[zähler].tif

Meine Frage: wie bekomme ich die "Zahl" (Name des Ordners der obersten Ebene) an die erste Stelle des Dateinamens, also z.b. "28-2016-03-17-Image1.tif"
ich muß sicher die Zeile "move-item" anpassen, oder die variable $newfolder, nur wie?
Danke!
Alexander

Content-Key: 6005456295

Url: https://administrator.de/contentid/6005456295

Printed on: April 28, 2024 at 15:04 o'clock

Member: michi1983
michi1983 Feb 16, 2023 updated at 14:23:40 (UTC)
Goto Top
Hallo,

kenne mich nicht aus mit powershell, aber würde es so versuchen:

move-item $_.Fullname -Destination "$newfolder\$batch-${d}-Image$cnt$($_.Extension)" -Verbose  

Keine Gewähr auf Richtigkeit.

Gruß
Member: alexander01
alexander01 Feb 16, 2023 at 14:59:48 (UTC)
Goto Top
klappt nicht (ganz)...
Ergebnis:
0-2016-03-17-Image1.tif
er schreibt die Zählvariable davor, ich brauch aber den Ordnernamen (hier "zahl")....
Danke
Alexander
Member: TK1987
Solution TK1987 Feb 16, 2023 at 21:37:41 (UTC)
Goto Top
Moin Alexander,

dass ist das Problem, wenn man mehrere Foreach-Objekt-Schleifen in einander verschachtelt. Die Werte der äußeren Schichten sind dann in den Inneren Schleifen nicht mehr verfügbar.

Entweder müsste man diese nochmals separat in eine Variable schreiben, oder eine andere Pipelinevariable deklarieren.

Die aus Performance sicht wohl beste Methode ist jedoch, statt dem Foreach-Object Cmdlet das Foreach Statement zu nutzen:
# Pfad bitte anpassen
$root = 'k:\quelle'  
$batch = 0
# Abfrage aller Ordner der ersten Ebene im Root-Ordner 
Foreach ($DIR in ls $root -Directory ) {
    # alle 5 Ordner anhalten und fragen
    if ($batch % 5 -eq 0){
        Read-Host "`nEnter drücken zum fortfahren für den nächsten Batch an Ordnern"  
    }
    # Unterordner abfragen deren Namen dem Datumsmuster entspricht
    Foreach ($SUB in ls $DIR.FullName -Directory | ?{$_.Name -match '(\d{1,2})\.(\d{1,2})\.(\d{4})'}) {  
        # Datum neu formatieren und an Variable übergeben 
        $d = [datetime]::ParseExact($matches,'M.d.yyyy',[cultureinfo]::InvariantCulture).toString('yyyy-MM-dd')  
        # neuen Ordner eine Ebene höher erstellen
        $newfolder = (Join-Path $SUB.Parent.FullName $d)
        md $newfolder -Force | out-null
        # Zähler initialisieren
        $cnt = 1
        # Alle *.tif Dateien des Unterordner "Images" in den neuen Ordner unter neuem Namen verschieben 
        Foreach ($FILE in ls "$($SUB.FullName)\Images" -File -Filter *.tif) {  
            move-item $FILE.Fullname -Destination "$newfolder\$DIR-$d-Image$cnt$($FILE.Extension)" -Verbose  
            $cnt++
        }
        # alten Ordner rekursiv löschen
        del $SUB.FullName -Force -Recurse
    }
    # evt. Steuerdateien löschen
    ls $DIR.Fullname -File | del -Force

    $batch++
    }
    pause
Ich kann es gerade nicht testen, meine aber alle Variablen entsprechend geändert zu haben.

Gruß Thomas
Member: alexander01
alexander01 Feb 17, 2023 at 05:44:22 (UTC)
Goto Top
danke! Ich teste es heute.
Gruß
Alexander
Member: alexander01
alexander01 Feb 17, 2023 at 16:51:59 (UTC)
Goto Top
klappt einwandfrei.
Vielen vielen Dank!
Gruß
Alexander