toweliee
Goto Top

PowerShell - Dateien umbenennen

Hallo,

ich möchte Dateien umbenennen, jedoch fehlen mir die Kenntnisse um den richtigen Ausdruck zu formulieren.
An sich weiß ich wie man mit get-child item und rename-item umgeht jedoch bekomme ich folgenden Fall nicht hin:

Habe in einem Ordner sehr viele Dateien die nach folgendem Schema umbenannt werden sollen:

—9876543210.abcdefg.pdf
—9876543211.abcdefg.pdf

Am Ende sollen der Dateiname so aussehen:

Abcdefg.—9876543210.pdf


Wie vermittele ich PowerShell, dass er die ersten 12 Zeichen hinten oder besser noch vor die file-Extension anhängt.

Danke für eure Hilfe face-smile

Content-Key: 663159

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

Printed on: May 9, 2024 at 04:05 o'clock

Member: Doskias
Solution Doskias Mar 15, 2021 updated at 08:29:07 (UTC)
Goto Top
Moin Toweliee,

da du hier keinen Code postest wie weit du bist, poste ich auch keinen Code, sondern nur den Weg zur Lösung face-wink

Den Befehl, den du braust ist Substring. schön beschrieben unter anderem Hier oder auch hier. Meine Vorgehensweise wäre dabei:

 $variable=get-childitem um die Dateien (?) zu finden
 $Dateiname=$variable.name
Dateiname in 3 Teile (ersten 12, Rest bist auf die Dateiendung, Dateiendung) mittels substring splitten
Die 3 Teile aus der Reihenfolge 1 - 2 -3 in die Reihenfolge 2 - 1 - 3 in eine neue Variable $neuer_Name speichern
Umbenennen Von $Dateiname in $Neuer Name

Viel Spass

Gruß
Doskias

Nachtrag: Hab es grade mal für dich gebaut und getestet: 5 Minuten, 10 Zeilen (ja ich hab es ausführlich gemacht).
Member: Toweliee
Toweliee Mar 15, 2021 at 09:10:11 (UTC)
Goto Top
Dankeschön. Ich werde mich später mit dem Befehl Substring auseinandersetzen und hören lassen ob ich das soweit geschafft habe. Ansonsten poste ich den Code den ich bis dahin kreiert habe.

Mit hat tatsächlich dieser Befehl gefehlt. Danke Dir!!! face-smile
Mitglied: 147669
Solution 147669 Mar 15, 2021 updated at 16:24:30 (UTC)
Goto Top
Oder man arbeitet mit Replace oder alternativ auch mit Split
ls 'd:\ordner' -File -Filter *.pdf | %{rename-item $_.Fullname -NewName {$_.Name -replace  '^(.{12})\.([^\.]+)(.*)','$2.$1$3'} -verbose -force}  
oder macht vorher nen Check mit -match und nutzt die Regex Submatches
ls 'd:\ordner' -File -Filter *.pdf | ?{$_.Basename -match '^(.{12})\.(.*)'} | %{rename-item $_.FullName -NewName {"$($matches[2]).$($matches[1])$($_.Extension)"} -verbose -force}  
Member: Toweliee
Toweliee Mar 15, 2021 at 10:57:39 (UTC)
Goto Top
Hallo habe mich jetzt etwas an dem Substring-Befehl ausprobiert.

$variable=get-childitem C:\ Dateipfad *pdf
$dateiname=$variable.Name
$result=$var.subtring(1,12)

irgendwas mache ich noch falsch. Ich bekomme die Fehlermeldung:

Es ist nicht möglich, eine Methode für einen Ausdruck aufzurufen, der den NULL hat.

Habe gerade echt Probleme damit die Dateinamen in Strings zu splitten. Bekomme ja noch nicht mal eine Teilung hin 😂
Member: Toweliee
Toweliee Mar 15, 2021 at 10:58:56 (UTC)
Goto Top
Ich Probiere mich mal an deinem Hinweis aus, Danke für deinen Beitrag face-smile
Member: Toweliee
Toweliee Mar 15, 2021 at 11:00:03 (UTC)
Goto Top
Habe mich übrigens bei $var.substring vertippt in den Klammern steht (0,12)
Member: Toweliee
Toweliee Mar 15, 2021 at 12:31:34 (UTC)
Goto Top
Hallo SchmitzKatz,

Danke für deine Antwort und deinen Code face-smile Inwiefern muss ich ihn anpassen, damit die Dateinamen geändert werden. Er sagt mir zwar dass er die Dateien umbenennt und das Ziel, aber leider ändern sich die Dateinamen nicht.
Member: Doskias
Solution Doskias Mar 15, 2021 at 13:31:50 (UTC)
Goto Top
Ausführlich und Schritt für Schritt anstand in einer Zeile:

Die Datei —9876543210.abcdefg.pdf befindet sich im Ordner C:\temp\test
$Ordner="c:\temp\test"  
$aktuelle_Datei=Get-ChildItem $Ordner
$Dateiname=$aktuelle_Datei.Name
$Dateilaenge=$Dateiname.Length
$Teil1=$Dateiname.Substring(0,12)
$Teil2=$Dateiname.Substring(12,$Dateilaenge-15)
$Teil3=$Dateiname.Substring($Dateilaenge-3)
$neuer_name=$Teil2+$Teil1+$Teil3
Rename-Item $Ordner\$aktuelle_Datei $neuer_name

Gruß
Doskias
Member: Toweliee
Toweliee Mar 15, 2021 at 14:08:01 (UTC)
Goto Top
Hallo Doskias,

Danke für deinen Code. Der Code bleibt leider in Zeile 6 hängen mit der Fehlermeldung: Die Länge darf nicht kleiner als Null sein.
Was mache ich jetzt schon wieder falsch? 😅
Member: Doskias
Solution Doskias Mar 15, 2021 updated at 14:21:55 (UTC)
Goto Top
Keine Ahnung :D

Prüfe mal den Dateinamen. Was macht Zeile 6?


Es nimmt den Substring und beginnt am 12ten Zeichen und zeigt dann Dateilänge (Zeile 4) minus 15 Zeichen an. Wieso minus 15 zeichen:
12 Sind im ersten Teil, 3 sind die Dateiendung. Wenn dein Dateiname zu kurz ist, dann ist Dateilaenge-15 kein gültiger wert mehr. Der Dateiname muss also mindestens 17 Zeichen lang sein.

Substring(a,b) beginnt an Position a und zeigt b Zeichen an
Substring (a) beginnt an Position a und zeigt alle folgenden Zeichen bis zum Ende an.

Gruß
Doskias
Member: Toweliee
Toweliee Mar 15, 2021 at 14:55:11 (UTC)
Goto Top
Meine Dateinamen sind ja sogar länger als oben angegeben xD oh man langsam bin ich am verzweifeln.

Habe halt bunte Mischung von Dateinamen drinnen. Habe nur versucht ein Muster darzustellen. Habe auch viele Dateien mit unterstrichen. Könnte man nicht auch eine Variante nehmen wie SchmitzKatz verwenden?

Die meisten Dateien werden nach diesem Schema benannt:

—9876543210_7035_02_010_98_ay.pdf

Wie schon gesagt, die ersten 12 Zeichen sollen vor die file-Extension.

Manchmal sind die Dateien auch durch Punkte getrennt.

Gibt es eine Möglichkeit, den Teil vor dem ersten Unterstrich/Punkt zu separieren, dann einen Teil der sich hinter diesem Unterstrich/Punkt befindet und dann die file- Extension zu separieren?


Sorry, dass ich das nicht vorher besser formuliert habe, was der am Ende entstandene Code eigentlich machen soll. Bin Neuling auf dem Gebiet und stelle mich noch ziemlich doof an. Danke für eure Hilfe und Geduld.
Member: Doskias
Solution Doskias Mar 15, 2021 at 15:22:06 (UTC)
Goto Top
Ja dann klappt das so nicht mit dem Skript. ich war von exakt der Bezeichnung ausgegangen.
da hilft dir dann *split*

$Splitten=($Dateiname).split(".")  
Splittet dabei den Dateinamen nach jedem Punkt. Du erhälst dann ein Array, welches du mit
$splitten
aufrufen kannst. 0 für den ersten Eintrag, 1 für den zweiten ...

Bei —9876543210.abcdefg.pdf hättest du entsprechend 3 Werte im Array, bei —9876543210_7035_02_010_98_ay.pdf nur 2.

Könnte man nicht auch eine Variante nehmen wie SchmitzKatz verwenden?
Klar. Die macht das gleiche, aber halt nur in einem Einzeiler. Ich bin nur ein Freund von Mehrzeilern, da Neulinge da eher verstehen wie Powershell funktioniert und arbeitet.

Wie schon gesagt, die ersten 12 Zeichen sollen vor die file-Extension.
Das ist mit meinem Skript möglich. Wenn du das verstanden hast musst du nur in Zeile 6 und 7 eine Kleinigkeit verändern, damit es geht ;)
Member: erikro
Solution erikro Mar 15, 2021 at 18:50:47 (UTC)
Goto Top
Moin,

mal ein ganz anderer Vorschlag: Nimm regex. Das ist flexibler und sicherer:

PARAM(

    $folder

)

$files = Get-ChildItem -Path $folder\*.pdf
foreach($file in $files) {

    $file.basename -match "(.*)\.(.*)"  
    $newbasename = $Matches[2] + "." + $Matches[1]  

    Rename-Item -path $file.fullname -NewName "$$(file.directory)\$($newbasename)$($file.extension)"  
}

Ungetestet. Das überlasse ich Dir. face-wink

hth

Erik
Member: Toweliee
Toweliee Mar 16, 2021 at 06:22:06 (UTC)
Goto Top
Guten Morgen Doskias,

an sich funktioniert der Code, allerdings erhalte ich wie du schon sagst mir 2 Arrays. Split 0 ist der komplette Dateiname und Split 1 ist die Dateiendung. Habe mich jetzt auch schon durch den Hinweis von SchmitzKatz an Matches ausprobiert. Habe da ich 4 unterstriche und einen Punkt+dateiendung bei den meisten Dateien habe 5 Matches erstellt und jedes Match einer Variable zugeordnet ($partn=$matches[n]) davor habe ich die Matches ähnlich wie SchmitzKatz definiert bloß eben mit unterstrichen. Leider ändert er auch damit nicht die Dateinamen. Habe danach mit new name die Matches aneinander gereiht.

Hast du vielleicht noch eine Lösung für mich?
Sowas womit ich den ersten Split nach dem ersten Unterstrich vornehmen kann. Den zweiten nach dem ersten Unterstrich und dem Zeichen vor der Datei Endung und den dritten Split mit dem Punkt und der dateiendung?

Habe jetzt ne Stunde rumprobiert und bin wieder mal am verzweifeln 😅

Danke im Voraus
Member: Doskias
Solution Doskias Mar 16, 2021 at 07:01:31 (UTC)
Goto Top
Wie ich dir gestern ja schon geschrieben habe musst du nur zwei Zeilen bei mir oben ändern:

$Ordner="c:\temp\test"  
$aktuelle_Datei=Get-ChildItem $Ordner
$Dateiname=$aktuelle_Datei.Name
$Dateilaenge=$Dateiname.Length
$Teil1=$Dateiname.Substring(0,12)
$Teil2=$Dateiname.Substring(12,$Dateilaenge-16)
$Teil3=$Dateiname.Substring($Dateilaenge-4)
$neuer_name=$Teil2+$Teil1+$Teil3
Rename-Item $Ordner\$aktuelle_Datei $neuer_name
Sollte eigentlich zuverlässig klappen, sofern du (a) immer mehr als 12 Zeichen im Dateinamen hast, zzgl. der Dateiendung, also 16 Zeichen gesamt und (b) immer nur Dateiendungen mit 3 Zeichen im entsprechenden Ordner hast.
Du kannst das ganze Skript natürlich noch verfeinern, indem du zum Beispiel mit
if ($Dateilaenge -gt 17)
Zeile 6 auf gültigkeit prüfst oder das ganzen Skript mit einer foreach-Schleife über den ganzen Ordner laufen lässt, anstatt einer Datei. Aber von deiner Aussage her, die da lautete, dass du *.pdf* hast, wo die ersten 12 Zeichen direkt vor die Dateiendung sollen und der Rest nach vorne rückt, sehe ich kein Problem mit meiner Lösung face-smile

Wenn die nicht klappt, dann solltest du uns vielleicht noch mal einige Informationen zu deinen genauen Anforderungen und dem Aufbau der Dateien geben.

Gruß
Doskias
Member: Toweliee
Toweliee Mar 16, 2021 at 07:01:56 (UTC)
Goto Top
Hallo Doskias,

habe es glaube ich fast. Es kommt noch die Fehlermeldung: Eine Datei kann nicht erstellt werden, wenn sie bereits vorhanden ist.
Member: Doskias
Solution Doskias Mar 16, 2021 at 07:04:08 (UTC)
Goto Top
Zitat von @Toweliee:

Hallo Doskias,

habe es glaube ich fast. Es kommt noch die Fehlermeldung: Eine Datei kann nicht erstellt werden, wenn sie bereits vorhanden ist.

Ob eine Datei vorhanden ist, lässt sich prüfen:
Test-Path $fileToCheck
Ergibt dann True oder False. Das ganze mit einer IF-Bedingung vor dem Umbenennen abfragen und du solltest keinen Fehler mehr bekommen
Member: Toweliee
Toweliee Mar 16, 2021 at 07:54:58 (UTC)
Goto Top
Hallo Doskias,

bekomme jetzt folgende Eingabeaufforderung

Cmdlet Test-Path an der Befehlspipelineposition 1
Geben Sie Werte für die folgenden Parameter an:
Path:

Was muss ich eingeben?
Das zählt die ganze weiter hoch. Path[n+1]
Member: Doskias
Solution Doskias Mar 16, 2021 at 07:57:16 (UTC)
Goto Top
Wenn du prüfen Willst ob unter c:\temp\ eine Datei mit dem Namen Test.pdf liegt, dann muss es so aussehen:

Test-Path C:\temp\Test.pdf

ansonsten hilft dir immer get-help Befehl also in dem Fall
 get-help test-path 
weiter
Member: Toweliee
Toweliee Mar 16, 2021 at 08:03:47 (UTC)
Goto Top
In dem Ordner habe ich ja sehr viele Dateien, mein Ziel ist ja eben dass ich nicht jede Datei einzeln anfassen muss.
Er zeigt mir leider immer noch an, dass die Dateien nicht vorhanden sind. Kann man diese Fehlermeldung nicht noch anders umgehen?
Member: Doskias
Solution Doskias Mar 16, 2021 at 08:18:22 (UTC)
Goto Top
Dafür gibt es ja foreach
$Ordner="c:\temp\test\"  
$Dateien=Get-ChildItem $Ordner
foreach ($aktuelle_Datei in $Dateien)
{
$Dateiname=$aktuelle_Datei.Name
$Dateilaenge=$Dateiname.Length
$Dateilaenge-3
$Teil1=$Dateiname.Substring(0,12)
$Teil2=$Dateiname.Substring(12,$Dateilaenge-16)
$Teil3=$Dateiname.Substring($Dateilaenge-4)
$neuer_name=$Teil2+$Teil1+$Teil3
Rename-Item $Ordner\$aktuelle_Datei $neuer_name
}
Habe es mit folgenden Dateien erfolgreich getestet
bild
Bei jedem Durchgang werden die ersten 12 Zeichen direkt vor die PDF-Endung geschrieben.
Member: Toweliee
Toweliee Mar 16, 2021 at 09:01:33 (UTC)
Goto Top
Es hat funktioniert!! :D

Danke dir für deine große Hilfe und für deine Geduld 👍🏼
Member: EleRoli
EleRoli Oct 19, 2023 at 11:54:42 (UTC)
Goto Top
Hallo!

Ich suche eine Möglichkeit, dass mehrere PDFs in einem Ordner unter Unterordner umbenannt werden

Hauptpfad wäre zB \\Server\Rechnungen\

Der Aufbau sieht so aus
\\Server\Rechnungen\01234\ (hier ist nur ein PDF drinnen)
\\Server\Rechnungen\8966544\ (hier sind drei PFDs drinnen)
\\Server\Rechnungen\46844444\ (hier ist nur ein PDF drinnen)
\\Server\Rechnungen\98981\ (hier sind zwei PDFs drinnen)
usw

Der soll dann in einer for-schleife alle Unterordner lt. Hauptpfad durchgehen und zuerst prüfen, ob im Unterordner eine PDF-Datei vorliegt mit Dateiname ER.pdf. Wenn nicht, dann soll das Script jene Datei ermitteln, die als erstes erstellt wurde (ältestes Erstelldatum) und diese in ER.pdf umbenennen. Weitere PDFs in diesem Unterordner soll er überspringen.

Wäre das Möglich?

LG Roland
Mitglied: 7907292512
7907292512 Oct 19, 2023 updated at 12:18:23 (UTC)
Goto Top
Zitat von @EleRoli:

Hallo!

Ich suche eine Möglichkeit, dass mehrere PDFs in einem Ordner unter Unterordner umbenannt werden

Hauptpfad wäre zB \\Server\Rechnungen\

Der Aufbau sieht so aus
\\Server\Rechnungen\01234\ (hier ist nur ein PDF drinnen)
\\Server\Rechnungen\8966544\ (hier sind drei PFDs drinnen)
\\Server\Rechnungen\46844444\ (hier ist nur ein PDF drinnen)
\\Server\Rechnungen\98981\ (hier sind zwei PDFs drinnen)
usw

Der soll dann in einer for-schleife alle Unterordner lt. Hauptpfad durchgehen und zuerst prüfen, ob im Unterordner eine PDF-Datei vorliegt mit Dateiname ER.pdf. Wenn nicht, dann soll das Script jene Datei ermitteln, die als erstes erstellt wurde (ältestes Erstelldatum) und diese in ER.pdf umbenennen. Weitere PDFs in diesem Unterordner soll er überspringen.

Wäre das Möglich?

LG Roland

$rootfolder = "\\Server\Rechnungen"  
foreach($dir in Get-ChildItem $rootfolder -Directory | ?{!$_.GetFiles("ER.pdf")}){  
    Get-ChildItem $dir.Fullname -File -Filter *.pdf | sort CreationTime | select -First 1 | rename-item -NewName "ER.pdf" -verbose  
}
Gruß sid.

ps. fürs nächste mal bitte beachten:
Discussion guidelines - The rules for our content
Keine Takeovers. Versuche nicht, Beiträge anderer Autoren mit Ihren Fragen zu anderen Themen zu übernehmen. Eröffne lieber einen neuen eigenen Beitrag.
Member: EleRoli
EleRoli Oct 19, 2023 at 12:38:40 (UTC)
Goto Top
Hallo Sid,

vielen Dank.

Das funktioniert bei mir nicht. Wenn ich die ps1-Datei ausführe, dann öffnet sich die Datei. Woran könnte das liegen?

LG
Mitglied: 7907292512
7907292512 Oct 19, 2023 updated at 12:51:16 (UTC)
Goto Top
Zitat von @EleRoli:
Das funktioniert bei mir nicht. Wenn ich die ps1-Datei ausführe, dann öffnet sich die Datei. Woran könnte das liegen?
Da fehlen bei Dir wohl vollkommen die Powershell Grundlagen ... > Rechtsklick "Mit Powershell ausführen"
Kapitel 1: Erste Schritte mit PowerShell
Und vorher bitte die Execution-Policy in einer elevated Shell anpassen falls nötig!
Set-ExecutionPolicy RemoteSigned

Und doch, das Skript läuft hier einwandfrei im Test! Ergo => Grundlagen rein pfeifen, dann wieder kommen.
Member: EleRoli
EleRoli Oct 19, 2023 updated at 13:29:54 (UTC)
Goto Top
Hallo Siddius,

besten Dank. Es ist gegangen.

Zum Testen habe ich nur die Ordnerstruktur lt. Beispiel genannt. Tatsächlich habe ich noch weitere Dimension an Unterordner.

Eigentlich sieht es so aus

\\Server\Rechnungen\01234\Unterordner 1\(hier sind drei PFDs drinnen)
\\Server\Rechnungen\01234\Unterordner 2\(hier ist nur ein PDF drinnen)
\\Server\Rechnungen\8966544\Mehrere Unterordner... (hier sind drei PFDs drinnen)
\\Server\Rechnungen\46844444\Mehrere Unterordner... (hier ist nur ein PDF drinnen)
\\Server\Rechnungen\98981\Mehrere Unterordner... (hier sind zwei PDFs drinnen)

Auf jeden Fall passt der zu untersuchende Startpfad \\Server\Rechnungen

LG Roland
Member: EleRoli
EleRoli Oct 19, 2023 at 14:31:20 (UTC)
Goto Top
Hallöchen,

hab mich selber bissl eingelesen und mit -Recursive ergänzt. Jetzt läufts wie ich es brauche.

LG Roland
Member: EleRoli
EleRoli Nov 09, 2023 updated at 13:54:31 (UTC)
Goto Top
Hallo,

ich habe den Code bissl umgeschrieben aber es geht nicht. Ziel ist, dass die in allen Unterordner die älteste Datei (Dateiname egal) herausgefiltert und eine Kopie mit Dateinamen er.pdf erstellt. Die älteste Datei soll bestehen bleiben.

$rootfolder = "\\Server\Rechnungen"    
Get-ChildItem $rootfolder -Directory -Recurse | ?{!$_.GetFiles("er.pdf")} | %{Get-ChildItem $_.Fullname -File -Filter *.pdf | sort CreationTime | select -First 1 | Copy-Item -Destination $_.FullName\"er.pdf"}    

Kann mir da bitte jemand weiterhelfen

LG Roland