af09940
Goto Top

Dateinamen umbenennen Namensteil suchen und ersetzen, bzw. ab Fundort den Rest löschen

Hallo zusammen,

Ich habe ein paar tausend Dateien in mehreren Unterverzeichnissen, die fast immer zu viele Zeichen im Dateinamen enthalten.

Beispiel:
"Anfang mit Leerzeichen dann SD Schlussteil und noch 12345678 1234.txt"

Die länge der Dateinamen ist nie gleich, aber der Suchstring, ab der der Dateiname gekürzt werden soll ist " SD "".

Beispiel einer korrekt umbenannten Datei wäre dann:
"Anfang mit Leerzeichen dann.txt"

Ich habe schon sehr viele Ansätze hier gefunden, aber zum Ziel hat es noch nicht geführt.
Fast hätte ich mit diesem Code mein Ziel erreicht:

for %%f in (* SD *.*) do @for /f "delims=SD" %%n in ('echo %%~f') do @echo ren "%%~f" "%%n%%~xf"

Aber hier wird nur EIN Zeichen zum Vergleich herangezogen. Nutzt mir also nichts.

Und wenn es dann auch noch für Unterverzeichnisse anwendbar wäre, hätte ich nochmals viel arbeit gespart. Muss aber nicht zwingend sein.

Wenn mir da jemand den rechten Tipp geben könnte, wäre das toll

Danke

Content-Key: 338085

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

Printed on: April 24, 2024 at 13:04 o'clock

Member: Kraemer
Kraemer May 17, 2017 at 14:46:29 (UTC)
Goto Top
Moin,

an deiner Stelle würde ich das in der Powershell mit regex lösen. Mal als Beispiel für ein regex:
'Anfang mit Leerzeichen dann SD Schlussteil und noch 12345678 1234.txt' -cmatch "^([a-zA-Z0-9 ]*) SD [a-zA-Z0-9 ]*(.txt)$"  
$matches[1]+$matches[2]

Dann musst du nur noch wissen, wie eine Liste mit deinen Dateien bekommst: gci -Recurse http://www.computerperformance.co.uk/powershell/powershell_recurse.htm

und wie man Dateien umbenennt: https://www.windowspro.de/script/rename-item-dateien-umbenennen-powershe ...

und was eine Pipeline ist: https://msdn.microsoft.com/de-de/powershell/scripting/getting-started/fu ...

und noch eine Kleinigkeit über Schleifen wie Foreach: https://www.windowspro.de/script/schleifen-powershell-foreach-while-do-u ...

Gruß
Mitglied: 132895
Solution 132895 May 17, 2017, updated at May 18, 2017 at 06:01:48 (UTC)
Goto Top
PS
gci 'd:\Ordner\*.txt' -Recurse | ?{$_.Basename -cmatch ' SD '} | rename-item -Newname {"$($_.Basename.split(' SD ',2))$($_.Extension)"}  
Batch
@echo off &setlocal Enabledelayedexpansion
for /f "delims=" %%a in ('dir /b /s /a-d "d:\ordner\*.txt" ^| find " SD "') do (  
    set "name=%%~na"  
    for /f "tokens=1 delims=#" %%b in ("!name: SD =#!") do ren "%%a" "%%b%%~xa"  
)
Gruß
Member: af09940
af09940 May 17, 2017 at 22:35:07 (UTC)
Goto Top
@Kraemer: Vielen Dank für Deinen Gedankenanstoß. Allerdings ist die PowerShell für mich TOTALES Neuland und ich müsste da wirklich bei Null anfangen. Die Zeit kann ich - wenigstens momentan - nicht aufbringen.

@132895
Auch Dir vielen Dank fürs Gehirnschmalz.
Ich habe die Batch nach Deinem Text erstellt. Ich habe noch jeweils ein Leerzeichen vor und nach dem ""find " SD " " eingefügt, denn nur die zwei Buchstaben SD könnten auch als Teil des "richtigen" Dateinamens vorkommen.

Dann habe ich zum Testen vor dem "ren" ein echo eingefügt, um die Funktion zu testen.

Und so weit lief es auch gut. Allerdings würde nach der Ausführung nicht der "erste Teil" des Dateinamens als neuer Name hergenommen, sondern alles HINTER dem " SD ". Also im Beispiel sähe der rename Befehl so aus:

ren 'Anfang mit Leerzeichen dann SD Schlussteil und noch 12345678 1234.txt' 'Schlussteil und noch 12345678 1234.txt'

Da ich die Funktion noch nicht ganz durchblicke, könntest Du bitte noch mal drüberschauen, wo der 2. Teil statt dem ersten Teil als neuer Name genommen wird?

Und der 1. Teil scheint ja den Suchbegriff " SD " noch zu beinhalten. Es müsste aber VOR dem Suchbegriff abgeschnitten werden.

Der finale Rename-Befehl für diese Datei müsste also lauten:

ren 'Anfang mit Leerzeichen dann SD Schlussteil und noch 12345678 1234.txt' 'Anfang mit Leerzeichen dann.txt'

Vielen Dank
Mitglied: 132895
132895 May 18, 2017 at 06:00:47 (UTC)
Goto Top
Ach so dann habe ich das missinterpretiert, s. Anpassung oben ...
Member: af09940
af09940 May 18, 2017 at 06:27:36 (UTC)
Goto Top
Wow, ich bin begeistert. Das mit den Tokens muss ich mir noch mal genauer anschauen. Hier liegt ja wohl der einzige Unterschied, ob da 1 oder 2 steht...

Vielen Dank, hast mir viel Mühe gespart...

Bis dann
Member: af09940
af09940 May 18, 2017 at 06:55:53 (UTC)
Goto Top
Ich hab schon ein bisschen damit herumexperimentiert und es klappt wirklich genau wie es soll, echt klasse, Danke noch mal.

Ich habe aber auch bemerkt, dass der Suchstring Case-Sensitiv ist und auch keine Platzhalter mag. Und da viel mir ein, dass ich schon einmal erfolglos ein anderes Problem, ähnlicher Natur hatte. Vielleicht hast Du ja Lust, es mal zu probieren...

Vorgabe ist (fast) der gleiche Dateiname: "Anfang mit Leerzeichen dann SD Schlussteil und noch 12345678 1234 und noch mehr Text.txt"

Hier ist das - wohl noch kompliziertere - Problem, dass die Ziffern "12345678 1234" gelöscht werden sollen. Die Anzahl der Ziffern ist immer gleich, 8 + Leerzeichen + 4. Die Ziffern sind natürlich bei jeder Datei unterschiedlich.

Lässt sich das mit einer Batch lösen?

Das ist jetzt nicht akut, aber auch da habe ich lange drüber gebrütet und - per Batch - keine Lösung gefunden. Vielleicht hast Du ja eine Idee...

Bis dann
Mitglied: 132895
Solution 132895 May 18, 2017 updated at 07:22:15 (UTC)
Goto Top
Zitat von @af09940:
Ich habe aber auch bemerkt, dass der Suchstring Case-Sensitiv ist
Das kannst du ja anpassen mit dem Schalter /i.

Vorgabe ist (fast) der gleiche Dateiname: "Anfang mit Leerzeichen dann SD Schlussteil und noch 12345678 1234 und noch mehr Text.txt"

Hier ist das - wohl noch kompliziertere - Problem, dass die Ziffern "12345678 1234" gelöscht werden sollen. Die Anzahl der Ziffern ist immer gleich, 8 + Leerzeichen + 4. Die Ziffern sind natürlich bei jeder Datei unterschiedlich.

Lässt sich das mit einer Batch lösen?
Du solltest dich mal mit Regular Expressions beschäftigen, damit sind solche Sachen ein Klacks!
@echo off
powershell -Executionpolicy ByPass -Command "gci 'c:\Ordner\*.txt' -Recurse | ?{$_.Basename -match '\d{8} \d{4}'} | rename-item -NewName {$_.Name -replace '\d{8} \d{4}',''}" -Force  
Bzw. kann das jedes Rename-Programm was mit Regex umgehen kann.
Member: af09940
af09940 May 18, 2017 at 12:24:50 (UTC)
Goto Top
Echt der Hammer. Wie viel Zeit ich da schon reingesteckt hab und Du schüttelst das so aus dem Handegelenk. Echt klasse. Danke...

Aber mir fehlt einfach das Wissen mit Powershell. Wenn ich Deinen Code lese, ist mir schon klar was da passiert, aber ich wüsste ja nicht mal, wie die Powershell aus ner Batch aufrufe, geschweige denn die ganzen Befehle und Schalter... Aber das schau ich mir ganz sicher mal näher an.

Mit Rename Programmen hab ich auch einiges versucht. Mal geht es nicht, weil es ein verbundenes Netzwerklaufwerk ist (warum auch immer...)
Oder bei einem anderen vielversprechenden Programm, das zwar dauernd abstürzt, aber die Funktion tatsächlich bot (nach einigem Suchen), aber dann kam der Punkt, dass es nach dem entfernen der Ziffern zu Duplikaten kommen würde. Es wurde dann ein Fenster angezeigt und ich hätte händisch alle Konflikte einzeln entfernen müssen. Unmöglich.

Um so mehr danke ich Dir ...

Bis dann ;)
Member: Kraemer
Kraemer May 18, 2017 at 12:31:43 (UTC)
Goto Top
Zitat von @af09940:
Wie viel Zeit ich da schon reingesteckt

Ich habe das Opening dieses Threads mit meinem ersten Post heute Vormittag einem Praktikanten in die Hand gedrückt. Sein Vorwissen: Er kennt Excel-Formeln recht gut und hat hin und wieder mal ein aufgezeichnetes VBA-Makro geändert.

Nach etwas über 1 Stunde und ohne vorher was über die Powershell gewusst zu haben, hatte er das Skript bis auf einen kleinen Fehler fertig.

Im Unterschied zu dir hat er nun aber was gelernt.

Gruß