mehrere Dateien in Unterordnern umbenennen
Hallo zusammen,
ich habe einen Hauptordner Z.B C:\test in dem es verschiedene Unterordner mit verschiedenen Tiefen gibt. In den Unterordner liegen Dateien mit der gleichen Endung und einem gleichen Muster, sie sind alle 5-stellig z.B. A1001.txt F5234.txt usw.
ich müsste nun alle Dateien umbenennen indem ich jeweils die ersten 2 Stellen mit einer 5-Stelligen Zahl ersetze. Also aus A1001.txt wird 12345001.txt 12345234.txt und so weiter.
Die 5 Stellige Zahl müsste ich abgefragt werden, oder ich baue es in eine vorhande Bat-Datei ein, in der %1 meiner 5-stelligen Zahl entspicht. Die erste Batsch rufe ich mit kopieren 12345 auf.
kann mir hier jemand helfen?
Danke
Gruß Matthias
[Edit Biber] Das eher mundartliche "umgenennen" im Titel in das dudenkonforme "umbenennen" geändert. [/Edit]
ich habe einen Hauptordner Z.B C:\test in dem es verschiedene Unterordner mit verschiedenen Tiefen gibt. In den Unterordner liegen Dateien mit der gleichen Endung und einem gleichen Muster, sie sind alle 5-stellig z.B. A1001.txt F5234.txt usw.
ich müsste nun alle Dateien umbenennen indem ich jeweils die ersten 2 Stellen mit einer 5-Stelligen Zahl ersetze. Also aus A1001.txt wird 12345001.txt 12345234.txt und so weiter.
Die 5 Stellige Zahl müsste ich abgefragt werden, oder ich baue es in eine vorhande Bat-Datei ein, in der %1 meiner 5-stelligen Zahl entspicht. Die erste Batsch rufe ich mit kopieren 12345 auf.
kann mir hier jemand helfen?
Danke
Gruß Matthias
[Edit Biber] Das eher mundartliche "umgenennen" im Titel in das dudenkonforme "umbenennen" geändert. [/Edit]
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 80307
Url: https://administrator.de/contentid/80307
Ausgedruckt am: 26.11.2024 um 05:11 Uhr
10 Kommentare
Neuester Kommentar
Ich hatte vor kurzen auch das Problem mit den Unterordnern, nur dass ich eine bestimmte Zeichenkette ersetzen musste.
"A.F.5 Rename your files 1.1" sollte das gehen, wenn die Zahl nach dem Buchstaben immer 4-stellig ist. Ansonst vielleicht irgendwie differenzieren.
Du könntest mit der Windows-Suche (F3 im Explorer) alle Dateien mit der Endung im Verzeichnis suchen. Die erhältst dann eine Liste der Entsprechenden. Durch Strg-A alle markieren und via Drag'n'Drop ins A.F.5 Ren... - Fenster schieben.
Da kannst du dann mittels LEFT und RIGHT solange 'experimentieren' bis es geht.
"A.F.5 Rename your files 1.1" sollte das gehen, wenn die Zahl nach dem Buchstaben immer 4-stellig ist. Ansonst vielleicht irgendwie differenzieren.
Du könntest mit der Windows-Suche (F3 im Explorer) alle Dateien mit der Endung im Verzeichnis suchen. Die erhältst dann eine Liste der Entsprechenden. Durch Strg-A alle markieren und via Drag'n'Drop ins A.F.5 Ren... - Fenster schieben.
Da kannst du dann mittels LEFT und RIGHT solange 'experimentieren' bis es geht.
Hallo Anfaenger99!
Etwa so:
Aus Sicherheitsgründen wird die Umbenennung nur angezeigt, aber, solange das REM am Beginn der letzten Zeile steht, nicht ausgeführt.
Zu berücksichtigen wäre, dass sich Namenskollisionen ergeben könnten (eine Datei mit gleichem Namen ist bereits vorhanden), welche sich in der obigen "Vorschau"-Version nicht durch Fehlermeldungen bemerkbar machen, da ja die Umbenennung noch nicht versucht wird.
Grüße
bastla
Etwa so:
@echo off & setlocal
set "Basis=C:\test"
set "Ext=*.txt"
set "Pre=12345"
::oder: set "Pre=%1"
::oder: set /p "Pre=5stellige Zahl eingeben: "
for /f "delims=" %%i in ('dir /s /b /a-d "%Basis%\%Ext%"') do call :ProcessFile "%%i"
goto :eof
:ProcessFile
set "FName=%~nx1"
echo %~f1 --^> %Pre%%FName:~2%
REM ren "%~f1" "%Pre%%FName:~2%"
Zu berücksichtigen wäre, dass sich Namenskollisionen ergeben könnten (eine Datei mit gleichem Namen ist bereits vorhanden), welche sich in der obigen "Vorschau"-Version nicht durch Fehlermeldungen bemerkbar machen, da ja die Umbenennung noch nicht versucht wird.
Grüße
bastla
Hallo Anfaenger99!
Ansonsten zu empfehlen: Online-Hilfe (zB "for /?") und jede Menge "Learning by Doing" ...
Grüße
bastla
... gutes Buch oder Dokument ...
Zu ersterem habe ich leider keinen Tipp, zu letzterem möchte ich Dich auf die Linksammlung und natürlich auf die vielen Beispiele unter Biber's Workshops) hinweisen.Ansonsten zu empfehlen: Online-Hilfe (zB "for /?") und jede Menge "Learning by Doing" ...
Grüße
bastla
Hallo Anfaenger99!
Die kombinierte Version könnte (ungetestet) etwa so aussehen:
Ein paar grundsätzliche Anmerkungen:
Warum einfaches Zusammenfügen der Einzelbatches nicht klappen konnte, liegt an der grundsätzlichen Struktur:
Jeder einzelne Batch war als "Hauptprogramm", welches ein oder mehrere Unterprogramme aufruft, konzipiert - auch nach der Zusammenfassung darf es nur ein Hauptprogramm geben, und die "Namen" der Unterprogramme müssen sich unterscheiden (was bei zweimal ":ProcessFile" nicht der Fall war).
Außerdem muss jedes Unterprogramm (und auch das Hauptprogramm) ein definiertes Ende haben - wenn es ganz am Ende eines Batches steht, ist eine explizite Angabe nicht erforderlich (sollte ich mir aber vielleicht trotzdem angewöhnen) - mitten drin muss aber ein "goto :eof" dieses Unterprogrammende signalisieren - bei ":ProcessPart" hatte dies gefehlt.
Wie schon oben erwähnt, habe ich meinen Entwurf nicht getestet, aber unter Berücksichtigung der genannten Aspekte sollte es Dir eigentlich auch selbst möglich sein, die Einzelteile entsprechend zu kombinieren.
Grüße
bastla
Die kombinierte Version könnte (ungetestet) etwa so aussehen:
@echo off & setlocal
set "Projekt=%1"
set "Ext=*.plf"
set "Zielpfad=I:\Konstruktion\Alfred\%1_%2"
set "Projektpfad=C:\Auftrag\%1_%2"
rd /s /q "%Zielpfad%"
md "%Zielpfad%"
md "%Zielpfad%\AW_AG\A2_je_1x"
md "%Zielpfad%\AW_AG\A2_je_2x"
md "%Zielpfad%\AW_AG\A3_je_1x"
md "%Zielpfad%\AW_AG\A3_je_2x"
md "%Zielpfad%\Formate"
xcopy /y /q "%Projektpfad%\%1%Ext%" "%Zielpfad%\Formate\"
for %%i in ("%Zielpfad%\Formate\%Ext%") do for /f "tokens=2 delims==" %%a in ('findstr "SelectedPaperName=" %%i') do call :ProcessFile "%%~fi" "%%a"
xcopy /y /q "%Projektpfad%\*G%Ext%" "%Zielpfad%\AW_AG\"
xcopy /y /q "%Projektpfad%\A2G%Ext%" "%Zielpfad%\AW_AG\A2_je_1x\"
xcopy /y /q "%Projektpfad%\A2G%Ext%" "%Zielpfad%\AW_AG\A2_je_2x\"
xcopy /y /q "%Projektpfad%\A3G%Ext%" "%Zielpfad%\AW_AG\A3_je_1x\"
xcopy /y /q "%Projektpfad%\A3G%Ext%" "%Zielpfad%\IW_IG\A3_je_1x\"
for /f "delims=" %%i in ('dir /s /b /a-d "%Zielpfad%\%Ext%"') do call :ProcessFile2 "%%i"
::Ende Hauptprogramm
goto :eof
:ProcessFile
set "FName=%~n1"
set DIN=
for %%p in (%~2) do call :ProcessPart %%p
set "NName=%DIN%%FName:~-3%%~x1"
if defined DIN (
if "%~nx1" neq "%NName%" (
echo %~1 --^> %NName%
ren %1 "%NName%"
)
)
goto :eof
:ProcessPart
set P=%1
if "%P:~0,1%" neq "A" goto :eof
if not defined DIN set DIN=%1
goto :eof
:ProcessFile2
set "FName=%~nx1"
echo %~f1 --^> %Projekt%%FName:~2%
ren "%~f1" "%Projekt%%FName:~2%"
goto :eof
- Da Du für den Zielpfad ja eine Variable verwendest, solltest Du dies auch konsequent von Anfang an tun - der Batch lässt sich dann leichter anpassen.
- Auch für die Erstellung der Verzeichnisstruktur ist es sinnvoller (anstelle eines "cd" und der Angabe relativer Pfade) gleich den vollen Pfad (unter Einsatz der Variablen) zu verwenden. "Mitten" im Pfad liegende Verzeichnisse ("AW_AG") musst Du nicht extra erstellen - "md" kann auch mehrere Ebenen auf einmal anlegen (für "A2_je_1x" ist eben "AW_AG" Voraussetzung, und daher wird dieses Verzeichnis automatisch erstellt).
- Auf das Erstellen der "AW_AG"-Verzeichnisstruktur könntest Du sogar überhaupt verzichten, wenn Du beim nachfolgenden "xcopy" den Schalter "/i" verwendest - aus Gründen der Übersichtlichkeit habe ich aber Deine Vorgangsweise beibehalten.
- Falls doch einmal ein Verzeichniswechsel sinnvoll oder notwendig wäre, kannst Du mit "cd /d LW:\Rootverzeichis\Unterverzeichnis" auch den Laufwerkswechsel mit dem selben Befehl erledigen (ist übersichtlicher). Alternativ dazu: "pushd" (mit dem Gegenstück "popd", um zum ursprünglichen Verzeichnis zurückzukehren).
- Im Zweifelsfall setze ich lieber ein Paar Anführungszeichen mehr, auch wenn es derzeit nicht unbedingt nötig wäre - sollte sich etwa der Zielpfad dahingehend ändern, dass Verzeichnisse mit Leerzeichen darin vorkommen, würde der Batch dann nämlich weiterhin funktionieren.
Warum einfaches Zusammenfügen der Einzelbatches nicht klappen konnte, liegt an der grundsätzlichen Struktur:
Jeder einzelne Batch war als "Hauptprogramm", welches ein oder mehrere Unterprogramme aufruft, konzipiert - auch nach der Zusammenfassung darf es nur ein Hauptprogramm geben, und die "Namen" der Unterprogramme müssen sich unterscheiden (was bei zweimal ":ProcessFile" nicht der Fall war).
Außerdem muss jedes Unterprogramm (und auch das Hauptprogramm) ein definiertes Ende haben - wenn es ganz am Ende eines Batches steht, ist eine explizite Angabe nicht erforderlich (sollte ich mir aber vielleicht trotzdem angewöhnen) - mitten drin muss aber ein "goto :eof" dieses Unterprogrammende signalisieren - bei ":ProcessPart" hatte dies gefehlt.
Wie schon oben erwähnt, habe ich meinen Entwurf nicht getestet, aber unter Berücksichtigung der genannten Aspekte sollte es Dir eigentlich auch selbst möglich sein, die Einzelteile entsprechend zu kombinieren.
Grüße
bastla
Hallo Anfaenger99!
Abgesehen davon kannst Du im Hauptprogramm nach der ja ohnehin vorgesehenen Zuweisung des ersten Parameters an die Variable %Projekt% in weiterer Folge diese verwenden (und auch den Parameter 2 durch die "sprechendere" Variable %Name% ersetzen):
Das Problem liegt allerdings eher darin, dass ja eigentlich die nach "Formate" kopierten Dateien in die Unterordner von "AW_AG" weiterverteilt werden sollten, und daher die "xcopy"-Zeilen etwa so aussehen müssten:
Nur bei der letzten Zeile hast Du übrigens (absichtlich?) "IW_IG" verwendet (durch den abschließenden "\" bei der Zielangabe wird übrigens dieser Ordner ebenfalls automatisch angelegt).
Noch eine Kleinigkeit: Mit der Umleitung ">nul" nach den Kopierbefehlen kannst Du die Ausgabe von "x Datei(en) kopiert" verschwinden lassen ...
Grüße
bastla
Ich gaube das liegt daran
set "FName=%~n1"
Nein; im Unterprogramm ist %1 der beim Aufruf übergebene Parameter und hat nichts mit dem beim Aufruf des Hauptprogrammes verwendeten %1 zu tun (was Du einfach mit einer Zeile "echo %1" im Unterprogramm überprüfen kannst).set "FName=%~n1"
Abgesehen davon kannst Du im Hauptprogramm nach der ja ohnehin vorgesehenen Zuweisung des ersten Parameters an die Variable %Projekt% in weiterer Folge diese verwenden (und auch den Parameter 2 durch die "sprechendere" Variable %Name% ersetzen):
@echo off & setlocal
set "Projekt=%1"
set "Name=%2"
set "Ext=*.plf"
set "Zielpfad=I:\Konstruktion\Alfred\%Projekt%_%Name%"
set "Projektpfad=C:\Auftrag\%Projekt%_%Name%"
...
xcopy /y /q "%Projektpfad%\%Projekt%%Ext%" "%Zielpfad%\Formate\"
...
Das Problem liegt allerdings eher darin, dass ja eigentlich die nach "Formate" kopierten Dateien in die Unterordner von "AW_AG" weiterverteilt werden sollten, und daher die "xcopy"-Zeilen etwa so aussehen müssten:
xcopy /y /q "%Zielpfad%\Formate\*G%Ext%" "%Zielpfad%\AW_AG\" >nul
xcopy /y /q "%Zielpfad%\Formate\A2G%Ext%" "%Zielpfad%\AW_AG\A2_je_1x\" >nul
xcopy /y /q "%Zielpfad%\Formate\A2G%Ext%" "%Zielpfad%\AW_AG\A2_je_2x\" >nul
xcopy /y /q "%Zielpfad%\Formate\A3G%Ext%" "%Zielpfad%\AW_AG\A3_je_1x\" >nul
xcopy /y /q "%Zielpfad%\Formate\A3G%Ext%" "%Zielpfad%\IW_IG\A3_je_1x\" >nul
Noch eine Kleinigkeit: Mit der Umleitung ">nul" nach den Kopierbefehlen kannst Du die Ausgabe von "x Datei(en) kopiert" verschwinden lassen ...
Grüße
bastla
... nachgereichte Erklärung:
:ProcessFile Sprungmarke; Beginn des Unterprogrammes
set "FName=%~n1" Da sich das Unterprogramm wie ein eigener Batch verhält, wird der übergebene Parameter (=Datei mit voller Pfadangabe) mit %1 angesprochen. "%~n1" liefert dann nur den Namen (ohne Pfad und Extension - siehe am Ende von der Hilfe mit "for /?"), welcher in der Variable %FName% gespeichert wird. Die Verwendung dieser Variablen ist erforderlich, da sich %1 nicht zeichenweise zerlegen lässt, wie das weiter unten benötigt wird.
set DIN= Variable %DIN% löschen
for %%p in (%~2) do call :ProcessPart %%p Schleife über alle durch Leerzeichen getrennten Bestandteile der Angabe hinter "SelectedPaperName=" (zB werden der Reihe nach als %%p verarbeitet: "Oce", "A2", "420x594" und "mm"); untersucht werden die Namensbestandteile im Unterprogramm ":ProcessPart" darauf hin, ob sie mit "A" beginnen - falls ja, wird (nur) der erste entsprechende Bestandteil in %DIN% zurückgegeben.
set "NName=%DIN%%FName:~-3%%~x1" Der neue Name ergibt sich aus der in %DIN% enthaltenen Papiergröße, den letzten 3 Stellen des Dateinamens und der Extension der übergebenen Datei.
if defined DIN ( sofern überhaupt ein passender Eintrag für die Papiergröße (mit "A" beginnend) gefunden wurde ...
if "%~nx1" neq "%NName%" ( ... und die Datei nicht ohnehin schon umbenannt ist (bisheriger Name inkl Extension "not equal" neuer Name) ...
echo %~1 --^> %NName%
ren %1 "%NName%"... machens wir's eben jetzt (und zeigen das zur Kontrolle noch vorher auf dem Bildschirm an - hier siehst Du übrigens auch den Inhalt von %1 - durch die Schreibweise %~1 ohne umgebende Anführungszeichen).
) Ende des "Ja"-Zweiges der zweiten Bedingung ...
) ... und analog für die erste Abfrage
goto :eof Ende Unterprogramm (und Rücksprung zum Hauptprogramm)
Grüße
bastla
:ProcessFile Sprungmarke; Beginn des Unterprogrammes
set "FName=%~n1" Da sich das Unterprogramm wie ein eigener Batch verhält, wird der übergebene Parameter (=Datei mit voller Pfadangabe) mit %1 angesprochen. "%~n1" liefert dann nur den Namen (ohne Pfad und Extension - siehe am Ende von der Hilfe mit "for /?"), welcher in der Variable %FName% gespeichert wird. Die Verwendung dieser Variablen ist erforderlich, da sich %1 nicht zeichenweise zerlegen lässt, wie das weiter unten benötigt wird.
set DIN= Variable %DIN% löschen
for %%p in (%~2) do call :ProcessPart %%p Schleife über alle durch Leerzeichen getrennten Bestandteile der Angabe hinter "SelectedPaperName=" (zB werden der Reihe nach als %%p verarbeitet: "Oce", "A2", "420x594" und "mm"); untersucht werden die Namensbestandteile im Unterprogramm ":ProcessPart" darauf hin, ob sie mit "A" beginnen - falls ja, wird (nur) der erste entsprechende Bestandteil in %DIN% zurückgegeben.
set "NName=%DIN%%FName:~-3%%~x1" Der neue Name ergibt sich aus der in %DIN% enthaltenen Papiergröße, den letzten 3 Stellen des Dateinamens und der Extension der übergebenen Datei.
if defined DIN ( sofern überhaupt ein passender Eintrag für die Papiergröße (mit "A" beginnend) gefunden wurde ...
if "%~nx1" neq "%NName%" ( ... und die Datei nicht ohnehin schon umbenannt ist (bisheriger Name inkl Extension "not equal" neuer Name) ...
echo %~1 --^> %NName%
ren %1 "%NName%"... machens wir's eben jetzt (und zeigen das zur Kontrolle noch vorher auf dem Bildschirm an - hier siehst Du übrigens auch den Inhalt von %1 - durch die Schreibweise %~1 ohne umgebende Anführungszeichen).
) Ende des "Ja"-Zweiges der zweiten Bedingung ...
) ... und analog für die erste Abfrage
goto :eof Ende Unterprogramm (und Rücksprung zum Hauptprogramm)
Grüße
bastla