adiewi
Goto Top

Gewisse Ordner kopieren und relativen Pfad erhalten. Wie?

Hallo,

Ich habe gerade angefangen ein bisschen mit batch zu programmieren (schon eine ziemliche Umstellung von C),
und bin dabei auf euer Forum gestoßen. Sind wirklich gute Tipps zu finden, leider passte noch keiner genau auf
mein Problem.

Also, ich habe zwei Ordner (z.B old und new). Im Ordner old befinden sich ältere Programmdateien, sowie Lokalisierungsordner,
im Ordner new die neuen Programmdateien. Die Struktur von old und new sieht folgendermaßen aus:

old
|---ordner1
| |---programmordner
| |---lokalisierungsordner
|---ordner2
| |---programmordner
| |---lokalisierungsordner

Die Lokalisierungsordner haben immer den gleichen Namen.
Ziel ist es alle Lokalisierungsordner mitsamt Pfad in den Ordner new zu kopieren, damit dort die Lokalisierung auch vorhanden ist.

Habe nun schon die folgende Batch-Datei geschrieben:
dir *407 /s /a d /B >> list.txt
for /f "tokens=5* delims=\" %%a in (list.txt) do (  
xcopy %%a\%%b newdir\%%b /I /H /E /Y
)

Das Problem ist nun, dass ich dieses skript nur in einer gewissen ordnertiefe ausführen kann (siehe tokens).
Ich habe schon versucht die strings in list.txt mit dem Set Befehl zu bearbeiten, um relative Pfade zu bekommen, hat
aber nicht funktioniert, da ich innerhalb des Set Befehls (z.B SET var=%%%a:%STR%=%) Variablen verwenden muss,
was er offensichtlich gar nicht mag.

Ich hoffe das war einigermaßen verständlich erklärt und mir kann jemand helfen.

Grüße

Content-Key: 122870

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

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

Mitglied: 60730
60730 Aug 17, 2009 at 10:53:21 (UTC)
Goto Top
Servus,

warum "so" umständlich?

xcopy quelle\*407 ziel\ /I /H /E /Y

sollte doch das gleiche bringen?

Gruß
Member: bastla
bastla Aug 17, 2009 at 14:42:43 (UTC)
Goto Top
Hallo ADiewi und willkommen im Forum!
hat aber nicht funktioniert, da ich innerhalb des Set Befehls (z.B SET var=%%%a:%STR%=%) Variablen verwenden muss, was er offensichtlich gar nicht mag.
Daran scheitert's erst später face-wink (außer Du verwendest zusätzlich ein "call") - zunächst einmal kannst Du für Schleifenvariablen keine Ersetzungen vornehmen (und, ganz nebenbei, auch keine Teilstrings bilden), daher zunächst in eine "gewöhnliche" Variable übertragen:
@echo off & setlocal
set "Quelle=D:\Ordner 1\Ordner 2\Ordner 3\old"  
set "Ziel=D:\Neuer Ordner1\Neuer Ordner2\new"  
for /f "delims=" %%a in ('dir /s /b /ad "%Quelle%\*407"') do call :ProcessDir "%%a"  
goto :eof

:ProcessDir
set "Absolut=%~1"  
call set "Relativ=%%Absolut:%Quelle%\=%%"  
xcopy /e /h /y %1 "%Ziel%\%Relativ%\">nul  
goto :eof
Grüße
bastla
Member: ADiewi
ADiewi Aug 17, 2009 at 18:25:07 (UTC)
Goto Top
Danke für die nette Begrüßung!

@timobeil:
Der kurze Befehl klappt leider nicht, da ich einen Ordner habe, der die Packete enthält, die wiederrum den Lokalisierungsordner enthält.
Xcopy nimmt aber * als Platzhalter für die Packetordner nicht an. Aber Danke.

@bastla:

Die Lösung hat super funktioniert. Ich hab den Code nur noch etwas modifizert, damit man auch einen Ordner daraufziehen kann und es
das aktuelle Verzeichnis als Arbeitsverzeichnis benutzt.

Super, wie schnell einem hier geholfen wird face-smile

@echo off & setlocal

set "Locale=0407"  
set "Quelle=%CD%\Old_Packages"  
if "%1" NEQ "" set "Quelle=%1"  
set "Ziel=%CD%\New_Packages"  
for /f "delims=" %%a in ('dir /s /b /ad "%Quelle%\%Locale%"') do call :ProcessDir "%%a"  
goto :eof

:ProcessDir
set "Absolut=%~1"  
call set "Relativ=%%Absolut:%Quelle%\=%%"  
xcopy /e /h /y %1 "%Ziel%\%Relativ%\">nul  
goto :eof
Member: ADiewi
ADiewi Aug 17, 2009 at 19:44:41 (UTC)
Goto Top
Eine Frage hat sich jetzt doch noch ergeben.
Die Packetordner tragen sowohl Namen als auch Versionsnummer (z.B. Packet_Name_1_00_1_2).
Wenn sich nun die Versionsnummer ändert, werden die Lokalisierungsordner nicht mehr in den
zugehörigen Packetordner kopiert, sondern es wird ein neuer erstellt, der nur den Lokalisierungsordner enthält.
Kann man die Versionsnummer enfernen?

Ich habe mir so etwas überlegt, allerdings wird der Platzhalter nicht akzeptiert.
Ich bekomme die Fehlermeldung: Datei 0407 nicht gefunden.

REM @echo off & setlocal

set "Locale=0407"  
set "Source=%CD%\OldPackages"  
if "%1" NEQ "" set "Source=%1"  
set "Target=%CD%\NewPackages"  
for /f "tokens=1,2 delims=_" %%a in ('dir /s /b /ad "%Source%\%Locale%"') do call :ProcessDir "%%a_%%b*\%Locale%"  
goto :eof

:ProcessDir
set "Absolute=%~1"  
call set "Relative=%%Absolute:%Source%\=%%"  
echo %Relative%
xcopy /e /h /y %1 "%Target%\%Relative%\">nul  
pause
goto :eof
Member: bastla
bastla Aug 17, 2009 at 19:57:47 (UTC)
Goto Top
Hallo ADiewi!

Dem Unterprogramm "ProcessDir" musst Du noch den vollständigen Pfad zum jeweiligen Ordner übergeben, aber Du kannst ja die Zerlegung dann für %Relative% vornehmen ...

... was dann etwa so aussehen könnte:
for /f "tokens=1* delims=\" %%a in ("%Relative%") do for /f "tokens=1,2 delims=_" %%i in ("%%a") do set "TargetAbsolute=%Target%\%%i_%%j\%%b\"
[Edit] Voraussetzung ist allerdings, dass sich der zu zerlegende Teil am Anfang des Relativpfades befindet ... [/Edit]

Grüße
bastla
Member: ADiewi
ADiewi Aug 17, 2009 at 22:08:17 (UTC)
Goto Top
Danke für die Antwort, bastla.

Ich habe den Code jetzt angepasst, komme aber nicht wirklich weiter. Ich denke das Problem liegt darin, dass ich die Relative Variable so anpassen
müsste, dass der Name des Paketordners im Ziel des Xcopy Befehls erhalten bleibt, aber die neue Versionsnummer aus dem neuen Verzeichnis
verwendet wird. Es würde hier genügen nach dem ersten '_' die Versionsnummer anzuhängen, da die meisten Pakete ohne Unterstrich im Name
auskommen, und den Rest dann manuell zu verschieben. Leider funktionieren Platzhalter im Verzeichnisnamen nicht, anders als bei Unix (schon eine
ziemliche Umstellung).

[Edit]Ach ja, die alten Packetordner sehen in etwa so aus: Packet_1_00_2, die neuen Packet_1_03_1.[/Edit]

Hier der Code:
REM @echo off & setlocal

set "Locale=0407"  
set "Source=%CD%\OldPackages"  
if "%1" NEQ "" set "Source=%1"  
set "Target=%CD%\NewPackages"  
for /f "delims=" %%a in ('dir /s /b /ad "%Source%\%Locale%"') do call :ProcessDir "%%a"  
goto :eof

:ProcessDir
set "Absolute=%~1"  
call set "Relative=%%Absolute:%Source%\=%%"  
for /f "tokens=1* delims=\" %%a in ("%Relative%") do for /f "tokens=1,2 delims=_" %%i in ("%%a") do set "TargetAbsolute=%Target%\%%i_%%j\%%b\"  
echo %Relative%
xcopy /e /h /y %1 "%TargetAbsolute%\">nul  
pause
goto :eof

Ich hoffe du hast die Geduld mir da nochmal zu helfen face-smile

Gruß
ADiewi
Member: bastla
bastla Aug 18, 2009 at 12:29:53 (UTC)
Goto Top
Hallo ADiewi!

Das könnte mit dem folgenden (ungetesteten) Unterprogramm gehen:
:ProcessDir
set "Absolute=%~1"  
call set "Relative=%%Absolute:%Source%\=%%"  
for /f "delims=_" %%i in ("%Relative%") do set "Packet=%%i"  
set "Version="  
for /f "tokens=1* delims=_" %%i in ('dir /b /ad "%Target%\%Packet%_*.*"') do set "Version=_%%j"  
for /f "tokens=1* delims=\" %%i in ("%Relative%") do set "TargetAbsolut=%Target%\%Packet%%Version%\%%j\"  
xcopy /e /h /y %1 "%TargetAbsolute%\">nul  
goto :eof
Das Einbeziehen des "_" in die Variable %Version% ist zwar nicht ganz sauber, verkürzt das Ganze aber, da ansonsten vorweg geprüft werden müsste, ob es im behandelten "Packet (inkl. Version)"-Ordnernamen tatsächlich einen "_" gibt ...

... wäre dies allerdings als sicher anzunehmen, dann besser so:
:ProcessDir
set "Absolute=%~1"  
call set "Relative=%%Absolute:%Source%\=%%"  
for /f "delims=_" %%i in ("%Relative%") do set "Packet=%%i"  
for /f "tokens=1* delims=_" %%i in ('dir /b /ad "%Target%\%Packet%_*.*"') do set "Version=%%j"  
for /f "tokens=1* delims=\" %%i in ("%Relative%") do set "TargetAbsolut=%Target%\%Packet%_%Version%\%%j\"  
xcopy /e /h /y %1 "%TargetAbsolute%\">nul  
goto :eof

Grüße
bastla
Member: ADiewi
ADiewi Aug 18, 2009 at 20:11:18 (UTC)
Goto Top
Danke, bastla
Ich werde den Code ausprobieren,sobald ich wieder zuhause bin. Schaut schon mal sehr vielversprechend aus.
Ich melde mich dann in zwei Tagen wieder.

Grüße,
ADiewi
Member: ADiewi
ADiewi Aug 22, 2009 at 09:30:19 (UTC)
Goto Top
So, wieder da face-smile

Ein dickes Danke an dich bastla!!
Das Skript funktioniert nun wie gewünscht, ich musste nur noch in der letzten for-Schleife TargetAbsolut durch TargetAbsolute ersetzten.
Ich poste hier auch mal die fertige Version.
@echo off & setlocal

set "Locale=0407"  
set "Source=%CD%\OldPackages"  
if "%1" NEQ "" set "Source=%1"  
set "Target=%CD%\NewPackages"  
for /f "delims=" %%a in ('dir /s /b /ad "%Source%\%Locale%"') do call :ProcessDir "%%a"  
goto :eof
:ProcessDir
set "Absolute=%~1"  
call set "Relative=%%Absolute:%Source%\=%%"  
for /f "delims=_" %%i in ("%Relative%") do set "Packet=%%i"  
for /f "tokens=1* delims=_" %%i in ('dir /b /ad "%Target%\%Packet%_*.*"') do set "Version=%%j"  
for /f "tokens=1* delims=\" %%i in ("%Relative%") do set "TargetAbsolute=%Target%\%Packet%_%Version%\%%j\"  
xcopy /e /h /y %1 "%TargetAbsolute%\">nul  
goto :eof