Fehler in einem PowerShell-Script zur Umbenennung
Hallo, Ihr habt mir vor einiger Zeit Hilfe bei der Erstellung eines PowerShell-Scriptes zur Umbenennung von Dateinamen gegeben.
Ich merke jetzt, das es bei bestimmten Konstellationen nicht fehlerfrei arbeitet. Kann mir hier jemand behilflich sein?
Ein Unterordner, dessen Namen ein Datum im Format M.T.JJJJ ist, bildet einen Teil des Namens von enthaltenen Dateien, die umbenannt und an eine andere Stelle verschoben werden.
Enthält das übergeordnete Verzeichnis nur einen solchen Unterordner (Name des Unterordners zum Beispiel "5.17.2019") klappt alles. Alle Dateien werden benannt nach dem Schema: [zahl]-jjjj-mm-tt-image[zahl].tif
Es funktioniert nicht mehr, wenn es zwei (oder mehrere?) Unterordner gibt, also z.B.:
5.17.2019
3.28.2022
Das Script (s.u.) benennt alle Dateien mit dem neu formatierten Datum des zweiten Unterordners (hier: 2022-03-28).
Ich habe ermittelt, das es mit dem Befehlsbestandteil $matches[0] zusammenhängt, weiß aber z.b. nicht, was [0] bewirkt.
Freue mich sehr über Hilfe!
Danke!
das Script:
Ich merke jetzt, das es bei bestimmten Konstellationen nicht fehlerfrei arbeitet. Kann mir hier jemand behilflich sein?
Ein Unterordner, dessen Namen ein Datum im Format M.T.JJJJ ist, bildet einen Teil des Namens von enthaltenen Dateien, die umbenannt und an eine andere Stelle verschoben werden.
Enthält das übergeordnete Verzeichnis nur einen solchen Unterordner (Name des Unterordners zum Beispiel "5.17.2019") klappt alles. Alle Dateien werden benannt nach dem Schema: [zahl]-jjjj-mm-tt-image[zahl].tif
Es funktioniert nicht mehr, wenn es zwei (oder mehrere?) Unterordner gibt, also z.B.:
5.17.2019
3.28.2022
Das Script (s.u.) benennt alle Dateien mit dem neu formatierten Datum des zweiten Unterordners (hier: 2022-03-28).
Ich habe ermittelt, das es mit dem Befehlsbestandteil $matches[0] zusammenhängt, weiß aber z.b. nicht, was [0] bewirkt.
Freue mich sehr über Hilfe!
Danke!
das Script:
# Pfad bitte anpassen
# benennt Bilder um in [Zahl]-jjjj-mm-tt-Image[xyz]
$root = 'k:\quelle'
$ziel = 'k:\fertig'
$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[0],'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
move-item "$newfolder\$DIR-$d-Image$cnt$($FILE.Extension)" -Destination $ziel -Verbose
$cnt++
}
# alten Ordner rekursiv löschen
del $SUB.FullName -Force -Recurse
}
# evt. Steuerdateien löschen
ls $DIR.Fullname -File | del -Force
$batch++
}
pause
Please also mark the comments that contributed to the solution of the article
Content-ID: 7988452936
Url: https://administrator.de/contentid/7988452936
Printed on: October 11, 2024 at 14:10 o'clock
5 Comments
Latest comment
Moin.
Ersetze $matches[0] durch $SUB.Name
Zur Erklärung, $matches[0] enthählt den Inhalt der zuletzt mit dem -match Operator durchgeführten Regex-Match Operation, das würde hier nur klappen wenn man mit foreach-object in der Pipeline statt einer normalen For-Schleife weiter macht. In diesem Fall ist es aber eine For-Schleife die die Ordner mit dem Datum einmalig ausfiltert und die Pipeline danach zuende ist und deswegen $matches[0] dann immer nur den letzten gefilterten Ordner enthält.
Gruß siddius
Ersetze $matches[0] durch $SUB.Name
Zur Erklärung, $matches[0] enthählt den Inhalt der zuletzt mit dem -match Operator durchgeführten Regex-Match Operation, das würde hier nur klappen wenn man mit foreach-object in der Pipeline statt einer normalen For-Schleife weiter macht. In diesem Fall ist es aber eine For-Schleife die die Ordner mit dem Datum einmalig ausfiltert und die Pipeline danach zuende ist und deswegen $matches[0] dann immer nur den letzten gefilterten Ordner enthält.
# Pfad bitte anpassen
# benennt Bilder um in [Zahl]-jjjj-mm-tt-Image[xyz]
$root = 'k:\quelle'
$ziel = 'k:\fertig'
$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($sub.Name,'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.Name)-$d-Image$cnt$($FILE.Extension)" -Verbose
move-item "$newfolder\$($DIR.Name)-$d-Image$cnt$($FILE.Extension)" -Destination $ziel -Verbose
$cnt++
}
# alten Ordner rekursiv löschen
del $SUB.FullName -Force -Recurse
}
# evt. Steuerdateien löschen
ls $DIR.Fullname -File | del -Force
$batch++
}
pause
Lass dir $d doch einfach mal auf der Konsole ausgeben ob das Datum da überhaupt drin steht hier klappt das im Test problemlos.
P.s. PowerShell kannst du auch step für step in der ISE laufen lassen und Breakpoints setzen dann kannst du schön auch selbst debuggen und dir die Variablen einzeln ansehen.
P.s. habe da oben noch etwas korrigiert was im Code nicht ganz stimmte.
P.s. PowerShell kannst du auch step für step in der ISE laufen lassen und Breakpoints setzen dann kannst du schön auch selbst debuggen und dir die Variablen einzeln ansehen.
P.s. habe da oben noch etwas korrigiert was im Code nicht ganz stimmte.
Na also, Selbsthilfe ist immer noch der beste Weg 👍. Kann ja hier keiner die Quelldaten sehen 😉.
Siddius
Siddius