alexander01
Goto Top

Powershell-Script zur Umstellung Datei-Namen gesucht

Hallo,
ich würde mich über eine Hilfestellung bei der Erstellung eines Powershell-Scriptes freuen.
Das Script soll alle .pdf-Dateien in einem Verzeichnis nach einer speziellen Bildungsvorschrift umbenennen.

bisheriges Format: Datum_Zahl_Text_Rest.pdf

in das Neue Format: Zahl-Datum-Text.pdf

mein bislang gebasteltes Script:

Get-ChildItem L:\Dateien\ -File | ForEach-Object {
    $Datum,$Zahl,$Test,$Rest = $_.Name -split '_',4  
    $Neu = $Zahl + "-" + $Datum + "-" + $Text + ".pdf"  
    $Neu
    }
Pause

liefert mir schon den korrekten Dateinamen (umgewandelte Position, umgewandelte Striche, Verkürzung, Dateiendung), aber wie benenne ich nun die alte Datei in die neue um?
ich habe viele Versuche mit Rename unternommen, aber PowerShell bringt immer Fehlermeldungen.
Danke für Hinweise!
Alexander

Content-ID: 1961880170

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

Ausgedruckt am: 22.11.2024 um 19:11 Uhr

1915348599
Lösung 1915348599 20.02.2022 aktualisiert um 15:39:06 Uhr
Goto Top
Get-ChildItem L:\Dateien -File -Filter *.pdf | rename-item -NewName {$_.Basename -replace '^(.*?)_(.*?)_(.*?)_.*','$2-$1-$3.pdf'}  
alexander01
alexander01 20.02.2022 um 17:44:20 Uhr
Goto Top
Danke, Pretty,
funktioniert fast!
Es kommt zum Phänomen:
bisheriges Format: Datum_Zahl_Text_Rest.pdf
beinhaltet "Rest" einen weiteren Unterstrich (sagen wir Rest1_Rest2), so stimmt die Neubildung des Namens nicht mehr.
statt: Zahl-Datum-Text.pdf entsteht Text-Datum-Zahl-Rest1.
Nun hab ich Schwierigkeiten mit der Interpretation der Hieroglyphen Deines Scriptes ...
Kannst Du das mal übersetzen, so das ich ggf. die Verbesserung einbauen könnte?
danke
Alexander
1915348599
1915348599 20.02.2022 aktualisiert um 18:23:30 Uhr
Goto Top
In dem Fall oben angepasst.
Hieroglyphen
Regular Expressions
alexander01
alexander01 20.02.2022 um 19:17:37 Uhr
Goto Top
bin im Moment überfordert.
replace generiert $1 aus allem, was vom Anfang an bis zum ersten Unterstrich steht., $2 wird gebildet von allem danach bis zum nächsten Unterstrich, $3 ebenso, danach kommt Rest, der nicht als Variable zur Verfügung steht (auch nicht benötigt wird).
warum ist bei Dateinamen, die der Vorschrift Datum_Zahl_Text_Rest1_Rest2.pdf folgen, dann $2 nicht der zweite Teil (Zahl) sondern Text ?
kannst Du einen Tipp geben?
Gruß und Danke
Alexander
1915348599
1915348599 20.02.2022 aktualisiert um 19:32:26 Uhr
Goto Top
Zitat von @alexander01:

bin im Moment überfordert.
Hab's doch oben schon an deinen Fall angepasst, läuft hier wie gewünscht ...

Guckst du, Online-Demo
https://tio.run/##bY6xCsIwFEX3fsUbAtFiAq0fIKgoLh3EycEQ2ycppLYkr1ZQvz22mR ...
alexander01
alexander01 21.02.2022 um 06:26:31 Uhr
Goto Top
Sorry, Pretty,
klappt bei mir bei diesem Fall nicht:
2019-08-17_13256_Text_Rest1_Re. st2.pdf
könnte der / ein Punkt im Text Rest2 stören? oder das / ein Leerzeichen?
Grüße
Alexander
1915348599
1915348599 21.02.2022 aktualisiert um 07:06:12 Uhr
Goto Top
Zitat von @alexander01:

Sorry, Pretty,
klappt bei mir bei diesem Fall nicht:
2019-08-17_13256_Text_Rest1_Re. st2.pdf
könnte der / ein Punkt im Text Rest2 stören? oder das / ein Leerzeichen?
Grüße
Alexander

Sicher geht das, guckst du hier das es geht ...
https://tio.run/##TYzNCoJAFEb3PsVFBizpDs5If6ugoGjjIlo3mN5QGFNmpgyqZzd11e ...
alexander01
alexander01 21.02.2022 um 07:06:47 Uhr
Goto Top
habe getestet, nicht der Punkt, sondern das Leerzeichen ist das Problem.
Enthält Rest2 (Datum_Zahl_Text_Rest1_Rest2_xyz...) ein Leerzeichen, funktioniert das Script nicht mehr.
wie schreibt man es so um, das es die Umbenennung immer richtig macht, egal, was nach dem Unterstrich hinter Text kommt?
Grüße
Alexander
1915348599
Lösung 1915348599 21.02.2022 aktualisiert um 07:28:02 Uhr
Goto Top
Blödsinn S.o. Online-Demo im letzten Comment läuft einwandfrei, das Leerzeichen ist wurscht und hat hier nichts zu sagen!
Du kannst den Regex alternativ auch so schreiben, kommt auf das selbe drauf raus und funktioniert ebenfalls einwandfrei.
Get-ChildItem L:\Dateien -File -Filter *.pdf | rename-item -NewName {$_.Basename -replace '^([^_]+)_([^_]+)_([^_]+).*','$2-$1-$3.pdf'}  
Beweis dass dies ebenfalls läuft hier
https://tio.run/##XYxNC4JAFEX3/opHCFPWGxylr21B0cZFtIscTF8ojCkzUwbVbzd12e ...

Das hier als weitere Alternative geht ebenfalls problemlos
Get-ChildItem L:\Dateien -File -Filter *.pdf | rename-item -NewName {($_.Basename.split('_')[1,0,2] -join '-') + '.pdf'} -verbose  
https://tio.run/##HYzLCsIwEEX3/YpBhLTaCU3F11ZBcdOFuBMJ1Y40kj5oohXUb49tNw ...

Ansonsten machst du einen Fehler beim übernehmen.
funktioniert das Script nicht mehr
"Funktioniert nicht" ist keine Fehlermeldung in einem Admin Forum!

I'm out.
alexander01
alexander01 21.02.2022 um 12:02:57 Uhr
Goto Top
Danke, Pretty,
mit dem zweiten Script klappt alles.
Danke für Deine Hilfe!
Gruß
Alexander
1915348599
1915348599 21.02.2022 aktualisiert um 12:45:55 Uhr
Goto Top
Zitat von @alexander01:

Danke, Pretty,
mit dem zweiten Script klappt alles.
Hier funktionieren alle Varianten im Test einwandfrei, mit deinen uns zur Verfügung gestellten Varianten. Sieht man ja schon an den Online-Demos, das ist eindeutig, ansonsten hast du uns etwas verschwiegen face-smile.
Danke für Deine Hilfe!
Bitte.
alexander01
alexander01 05.03.2022 um 09:10:28 Uhr
Goto Top
Hallo, Pretty,
kannst du mir nochmals bei 2 Problemen halfen?
im oben genannten Sachverhalt habe ich jetzt deinen Vorschlag eingebaut:

ls $_.FullName -File | rename-item -NewName {$_.Basename -replace '^([^_]+)_([^_]+)_([^_]+).*','$2-$1-$3.pdf'} -Verbose  

wie müsste man ihn verändern, damit das Script vor Umbenennung prüft, ob eine Datei mit dem Namen (der sich ergeben würde) schon existiert und die zweite neue Datei (und ggf. weitere) mit einem zusätzlichen "-(1...)" versieht?

wie müsste man das Script verändern, um die Variable $3 weiter anzupassen?
Beispiel: wenn $3 = "xy" dann wird $3 = "z", sonst bleibt sie.
Danke !!
Alexander
1915348599
1915348599 05.03.2022, aktualisiert am 06.03.2022 um 11:29:42 Uhr
Goto Top
Hatte man sich ja auch mal vorher überlegen können ....
Get-ChildItem L:\Dateien -File -Filter *.pdf | %{
    if ($_.Basename -match '^([^_]+)_([^_]+)_([^_]+)'){  
         $part1 = $matches[1]
         $part2 = $matches[2]
         $part3 = $matches[3]
         switch -regex ($part3){
              '^xy$' {$part3 = 'z'}  
              '^Haus.*' {$part3 = 'v'}  
         }
         $newname = "$part2-$part1-$part3.pdf"  
         $cnt = 1
         while(Test-Path "$($_.DirectoryName)\$newname"){  
              $newname = "$part2-$part1-$part3-$cnt.pdf"  
              $cnt++
         }
         rename-item $_.Fullname -NewName $newname -verbose
     }
}
alexander01
alexander01 05.03.2022 um 10:25:28 Uhr
Goto Top
Danke!
Powershell gibt den Fehler aus: Eine Datei kann nicht umbenannt werden, wenn sie bereits vorhanden ist.
Muß ich "Test-Path" anpassen?
1915348599
1915348599 05.03.2022 aktualisiert um 10:34:00 Uhr
Goto Top
Was vergessen, angepasst.
alexander01
alexander01 05.03.2022 um 10:43:51 Uhr
Goto Top
danke.
bin beeindruckt, klappt.
Vielen Dank !!!
Gruß
alexander
alexander01
alexander01 06.03.2022 um 09:50:34 Uhr
Goto Top
Pretty, darf ich nochmals um eine Idee bitten?
konkret geht es um den Befehl switch:

switch($part3){
              'xy' {$part3 = 'z'}  
         }

Wenn ich mehrere (werden sicher bis zu 10) Bedingungen prüfen möchte, und im Falle "true" eine entsprechende Umschreibung habe möchte, wie verknüpfe ich die Abfragen? Getrennt durch ein Sonderzeichen? Oder muß ich jedesmal den Switch-Befehl (also den Syntax-Block von oben) neu schreiben?
Danke!!
Alexander
1915348599
1915348599 06.03.2022 aktualisiert um 10:13:46 Uhr
Goto Top
Oder muß ich jedesmal den Switch-Befehl (also den Syntax-Block von oben) neu schreiben?
Blödsinn...Einfach mal selber in die Doku schauen das beantwortet dir die Frage von selbst wie man der Switch-Anweisung mehrere Bedingungen hinzufügt, genau dafür wurde die ja erfunden ...
Alles, was Sie schon immer über die switch-Anweisung wissen wollten
alexander01
alexander01 06.03.2022 um 10:13:26 Uhr
Goto Top
danke!
ich versuche mein Glück.
Danke für den Tipp.
alexander
alexander01
alexander01 06.03.2022 um 10:56:55 Uhr
Goto Top
gelesen und umgesetzt.
Danke.
schwieriger:
wenn der zu vergleichende Parameter 'xy' nur im Ansatz bekannt ist, der Rest der zeichenkette also egal oder unbekannt, wird's schon wieder komplex für mich.
Beispiel:
'Haus' obwohl der String "Haushalt" oder auch "Haus am See" heißt
Primitiv ausgedrückt Haus* (mit PLatzhalter)
'[Haus]'klappt nicht.
1915348599
1915348599 06.03.2022 aktualisiert um 11:04:55 Uhr
Goto Top
Dafür hat Switch den -regex Parameter 😉

switch -regex ($part3){
      '^xy$' {$part3 = 'z'}  
      '^Haus.*'  {$part3 = 'v'}  
}
alexander01
alexander01 06.03.2022 um 11:05:44 Uhr
Goto Top
..ok.
ich hatte getestet.
der Punkt fehlte.
;-(
danke
alexander01
alexander01 06.03.2022 um 11:22:54 Uhr
Goto Top
matches[2] und matches[1] werden verschluckt durch die Prüfung mit -regex

$newname = "$($matches[2])-$($matches[1])-$part3.pdf" wird "--v.pdf"
1915348599
1915348599 06.03.2022 um 11:26:34 Uhr
Goto Top
Weise ihnen vorher Variablen zu ...
alexander01
alexander01 06.03.2022 um 11:26:57 Uhr
Goto Top
ok, ich versuche es.
danke
alexander01
alexander01 06.03.2022 um 11:31:04 Uhr
Goto Top
danke.
klappt.
face-wink
Gruß
alexander