Verzeichnisnamen nach längster Datei innerhalb umbenennen?

German support forum

Moderators: white, Hacker, Stefan2

Post Reply
User avatar
versalzen
Power Member
Power Member
Posts: 666
Joined: 2003-09-16, 11:52 UTC
Location: kölle, linksrheinisch.

Verzeichnisnamen nach längster Datei innerhalb umbenennen?

Post by *versalzen »

Hallo und alaaaf!

ein jemand möchte gerne alle Unterverzeichnisse eines Ordners so umbenennen, wie die Datei mit dem längsten Namen innerhalb des jeweiligen Unterverzeichnisses. (Ohne Dateierweiterung)

Wüsste hier jemand, ob und wie das wohl mit Hausmitteln des TC geht?
Oder ein anderes Tool, denn es handelt sich um einige hunderte von Verzeichnissen...

Ein Beispiel:

Vorher:
Hauptordner\Unterverzeichnis1\Datei1.ext
Hauptordner\Unterverzeichnis1\Datei_mit_längstem_Dateinamen.ext
Hauptordner\Unterverzeichnis1\Datei2.ext

Nachher:
Hauptordner\Datei_mit_längstem_Dateinamen\Datei1.ext
Hauptordner\Datei_mit_längstem_Dateinamen\Datei_mit_längstem_Dateinamen.ext
Hauptordner\Datei_mit_längstem_Dateinamen\Datei2.ext

Seid bedankt und prost!
Was nützt der Löffel für die Weisheit, wenn man zu weit vom Suppentopf entfernt sitzt?

Mario
User avatar
Stefan2
Power Member
Power Member
Posts: 4158
Joined: 2007-09-13, 22:20 UTC
Location: Europa

Post by *Stefan2 »

Hmmm, eventuell

1) ein Backup vom Hauptordner erstellen
2) PowerShell starten
3) in Hauptordner\Unterverzeichnis1\ wechseln
4) dieses PowerShell Skript ausführen
[face=timesnewroman]
$Len=0;ls|%{$CurLen=$_.Name.length;IF($CurLen -gt $Len){$Len=$CurLen; $NewName=$_.BaseName; $Dir=$_.DirectoryName}};cd..;ren -path $Dir -NewName $NewName
[/face]



LS = Get-ChildItem
% = ForEach-Object
ren = Rename-Item


LS und DIR sind Aliase für Get-ChildItem, damit wird der Ordnerinhalt aufgelistet. (Es wird hier nicht nach Dateien und Ordner unterschieden)
Mit dem | Pipe-Zeichen wird das Ergebnis des LS-Befehl an "die Pipeline" übergeben.
%{...} is ein Alias für ForEach-Object {...}, damit wird jedes übergebene Object (hier; jede Datei) einzeln behandelt.
Ist die Länge des Dateinamen größer als das vorherige Ergebnis, wird diese Größe benutzt und sich der aktuelle Dateinamen gemerkt.
Wenn es kein weiteres Object mehr in der Pipeline gibt, wird mittels CD.. aus dem Ordner gegangen.
Danach wird der gerade bearbeitete Ordner mit dem gemerkten Namen umbenannt.
Fertig.



Als Nächstes könnte man um dieses Skript herum eine ForEach Schleife bauen und auf den Hauptordner loslassen...
User avatar
versalzen
Power Member
Power Member
Posts: 666
Joined: 2003-09-16, 11:52 UTC
Location: kölle, linksrheinisch.

Post by *versalzen »

Hey Danke!

Das Snippet funktioniert händisch in der PowerShell prima.

Allerdings ist es mir überhauptnicht gelungen,
a) eine normale Batch-Schleife drumherum zu bauen, die das Snippet mit "powershell -command" aufruft,
b) den Syntax von ForEach oder die enstandenen Fehlermeldungen "bla darf nur am Anfang verwendet werden, etc..." zu verstehen um das Snippet dort miteinzubinden,
c) es mit einfachen oder komplexen Mitteln auf mystische oder logische Weise, irgendwie hinzubekommen, das sich eine Schleife um das Snippet bildet, die das tut, was ich gerne hätte.

Hast Du nen Vorschlag, wie ich das Snippet in eine Schleife -wie auch immer geartet- einbinden kann, so das ich sie im aktuellen Verzeichnis loslassen kann?

Ich bin erstmal davon ab, das Dingen für spätere Zwecke als Vorlage für evtl. nochmaliges Vorkommen so einer Anforderung speichern zu wollen; mir ist es momentan nur lieb, wenn es für das aktuelle Verzeichnis läuft.

Sei bedankt auf jeden Fall für das CodeSnippet. Das macht Eindruck.
Was nützt der Löffel für die Weisheit, wenn man zu weit vom Suppentopf entfernt sitzt?

Mario
User avatar
Stefan2
Power Member
Power Member
Posts: 4158
Joined: 2007-09-13, 22:20 UTC
Location: Europa

Ordner umbenennen nach längster Datei mittels PowerShell

Post by *Stefan2 »

Hi,

Einfach ein weiteres "dir | ForEach{ ... }" drumherum setzen.

Oder, je nach Anforderung ein "dir | Where{$_.PSisContainer -eq $true} |ForEach{ ... }" um wirklich nur Ordner zu bearbeiten.

Etwa so:
[face=timesnewroman]Get-ChildItem |
Where-Object{$_.psiscontainer -eq $true}|
ForEach-Object{cd $_.Name; $Len=0; Get-ChildItem|
ForEach-Object{$CurLen=$_.Name.length; IF($CurLen -gt $Len){$Len=$CurLen; $NewName=$_.BaseName; $Dir=$_.DirectoryName}}; cd..; Rename-Item -Path $Dir -NewName $NewName}
[/face]


Oder in Kurzform mit Aliase:
[face=timesnewroman]
ls | ?{$_.psiscontainer -eq $true}| %{cd $_.Name; $Len=0;ls|%{$CurLen=$_.Name.length;IF($CurLen -gt $Len){$Len=$CurLen; $NewName=$_.BaseName;$Dir=$_.DirectoryName}}; cd..; ren -Path $Dir -NewName $NewName}
[/face]



Aber Achtung, das Skript wurde nur an Beispieldateien getestet und hat keine Fehlerbehandlung.
Daher am Besten den Hauptordner mittels Subst als Laufwerk mappen,
dann kann das Skript nicht "ausbrechen" und unerwünschte Verzeichnisse oberhalb umbenennen.

- Backup der originalen Daten
- starte PowerShell
C:\Users\name>subst B: "D:\rive\path\Hauptordner"
C:\Users\name>B:
B:\> ls | ?{$_.psiscont <--- das Skript ausführen (als eine lange Zeile, oder häppchenweise. wie oben umgebrochen)


Sollte man solch ein Skript häufiger einsetzen, schreibt man es am Besten in eine Skriptdatei *.ps1
und spendiert ihm eine umfangreiche Fehlerbehandlung. Dann kann man sich auch das subst sparen.
User avatar
versalzen
Power Member
Power Member
Posts: 666
Joined: 2003-09-16, 11:52 UTC
Location: kölle, linksrheinisch.

Re: Ordner umbenennen nach längster Datei mittels PowerShell

Post by *versalzen »

Dank Dir für die sehr ausführliche Hilfe und die Beispiele!
Das Projekt hab ich nun händisch erledigt, doch fürs nächste Mal ist es notiert.
Was nützt der Löffel für die Weisheit, wenn man zu weit vom Suppentopf entfernt sitzt?

Mario
Post Reply