mapl99sb
Goto Top

Batchprogramm unter WinXP

Hallo allerseits,

ich habe folgendes Problem: ich will Dateien, die in einem Quell-Ordner liegen per Batch in mehrere andere Ziel-Ordner kopieren. Die Zielordner sind Unterordner und entsprechen in den ersten 4 Stellen den ersten 4 Stellen der zu kopierenden Dateien. Bestehende, gleichnamige Dateien im Zielordner sollen überschrieben werden. Es soll ein kurzes Protokoll erstellt werden, damit klar ist, ob alle Quelldateien in den Zielordnern angekommen sind.

Bsp.:

Quellpfad ist c:\temp

Dateien darin lauten:
1000_a.pdf
1000_b.pdf
1000_a.png
1000_b.png
1010_a.png
2000_a.pdf
2000_a.png

Zielpfad ist d:\test
Die Unterordner dazu heissen (sie existieren schon):
d:\test\1000_x\
d:\test\1010_z\
d:\test\2000_y\

Am Ende sollte es so aussehen:

d:\test\1000_x enthält 1000_a.pdf, 1000_b.pdf, 1000_a.png, 1000_b.png
d:\test\1010_z\ enthält 1010_a.png
d:\test\2000_y enthält 2000_a.pdf, 2000_a.png

Das Ganze soll als Batchdatei unter Windows laufen.

Ich habe mit folgendem Batch leider nur einen Teilerfolg erreicht, da das Programm immer neue Pfade anlegt und nicht die bestehenden benutzt:

for %a in (c:\temp\*.*) do @for /f "delims=_ tokens=1" %i in ("%~nxa") do xcopy /I /Y %a c:\temp\%i\

Ein weiterer Versuch scheiterte auch, da ich das CD-Kommando nicht mit einem vernünftigen Wert versorgen kann:


for %%a in (c:\temp\*.*) do @for /f "delims=_ tokens=1" %%i in ("%%~nxa") do call :loop
:loop
cd %%i*
xcopy /I /Y c:\temp\%%a
cd ..

Kann mir jemand helfen???

Vielen Dank und viele Grüsse,
MAPL

Content-Key: 154091

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

Printed on: April 20, 2024 at 05:04 o'clock

Member: bastla
bastla Nov 01, 2010 at 06:26:14 (UTC)
Goto Top
Hallo mapl99sb und willkommen im Forum!

Das könnte etwa so gehen:
@echo off & setlocal
set "Quelle=c:\temp"  
set "Ziel=d:test"  
set "Prot=%Quelle%\Protokoll_%date:~-4%-%date:~-7,2%-%date:~-10,2%_%time:~,2%%time:~3,2%%time:~6,2%.txt"  
set "Prot=%Prot: =0%"  

del "%Prot%" 2>nul  
pushd "%Quelle%"  
for /f "tokens=1* delims=_" %%i in ('dir /b /a-d *_*.* 2^>nul') do (  
    set "Done="  
    for /d %%a in ("%Ziel%\%%i_?") do if not defined Done (  
        copy "%%i_%%j" "%%a" >nul  
        set "Done=True"  
    )
)
popd

for /d %%a in ("%Ziel%\*_?") do call :ProcessDir "%%a"  
goto :eof

:ProcessDir
set "Zeile=%~f1 enthaelt"  
for /f "delims=" %%i in ('dir /b /a-d %1 2^>nul') do call :ProcessFile "%%i"  
>>"%Prot%" echo %Zeile:~,-1%  
>>"%Prot%" echo\  
goto :eof

:ProcessFile
set "Zeile=%Zeile% %~1,"  
goto :eof
[Edit] Fehlendes Anführungszeichen am Ende der Zeile 29 ergänzt [/Edit]

Mit einer alternativen Schreibweise der Protokolleinträge ließe sich das noch kompakter formulieren:
@echo off & setlocal
set "Quelle=c:\temp"  
set "Ziel=d:test"  
set "Prot=%Quelle%\Protokoll_%date:~-4%-%date:~-7,2%-%date:~-10,2%_%time:~,2%%time:~3,2%%time:~6,2%.txt"  
set "Prot=%Prot: =0%"  

del "%Prot%" 2>nul  
pushd "%Quelle%"  
for /f "tokens=1* delims=_" %%i in ('dir /b /a-d *_*.* 2^>nul') do (  
    set "Done="  
    for /d %%a in ("%Ziel%\%%i_?") do if not defined Done (  
        copy "%%i_%%j" "%%a" >nul  
        set "Done=True"  
    )
)
popd

for /d %%a in ("%Ziel%\*_?") do (  
    echo %%~fa
    dir /b /a-d %%a 2>nul
    echo\
)>>"%Prot%"  
Nur als Anmerkung: Protokolliert wird in beiden Fällen nicht der Kopiervorgang, sondern der Ordnerinhalt nach dem Kopieren (es war ja "angekommen" gefragt) ...

Zum jeweiligen Zielordner wäre noch zu erwähnen, dass in den ersten Ordner, dessen Name mit "<Teil 1 Dateiname>_" (also: Zeichenkette des Dateinamens bis zum ersten "_" + "_") entspricht, kopiert wird (auch wenn nach dem "_" nix oder mehr als ein Zeichen folgt - daher auch nach "1000_" oder "1000_abc").

Grüße
bastla
Member: mapl99sb
mapl99sb Nov 04, 2010 at 18:00:39 (UTC)
Goto Top
Hallo bastla,
danke für das Coding. Super.

Hat auch fast alles geklappt. Musste nur das ? in ("%Ziel%\%%i_?") und ("%Ziel%\*_?") in einen * ändern, dann klappte das Kopieren.

Was noch nicht klappt ist das Protokoll. Er zeigt mir nur die Pfade an, nicht die Dateien im Zielpfad.
Ausserdem werden alle Unterverzeichnisse im Zielverzeichnis angezeigt und nicht nur die, in die etwas hineinkopiert wurde.

Hast du eine Idee, woran es liegen könnte?

Viele Grüsse,
MAPL
Member: bastla
bastla Nov 04, 2010 at 18:08:03 (UTC)
Goto Top
Hallo mapl99sb!
Was noch nicht klappt ist das Protokoll. Er zeigt mir nur die Pfade an, nicht die Dateien im Zielpfad.

Hast du eine Idee, woran es liegen könnte?
Am "?" ? face-wink Nö - das in Zeile 18 hattest Du ja auch schon gefunden ...

Mach doch mal aus dem "echo off" ein "echo on" und starte den Batch aus einem CMD-Fenster bzw füge am Ende noch eine Zeile mit "pause" hinzu - dann siehst Du, was genau passiert (und hoffentlich auch, warum etwas nicht passiert) ...

Außerdem kann's nicht schaden, die Zeile 20 auf
dir /b /a-d "%%a" 2>nul
zu ändern ... (Alle angegebenen Zeilen beziehen sich auf den zweiten Ansatz.)

[Edit] Im ersten Batch fehlte in Zeile 29 das schließende Anführungszeichen - ist oben bereits nachgetragen (auch wenn's daran eigentlich nicht gelegen haben sollte); falls Du auch diesen Batch mit "pause" testen wolltest, müsste das zwischen die Zeilen 18 und 19 ... [/Edit]

Grüße
bastla
Member: mapl99sb
mapl99sb Nov 06, 2010 at 16:52:54 (UTC)
Goto Top
Hi bastla,
habe noch einen -hoffentlich- letzten Punkt: das Protokoll wirft immer alle Pfade des Zielverzeichnisses aus.
Ich will aber nur die sehen, die auch geändert wurden. Ich habe deshalb das Coding des "Protokoll"-Teils ein wenig geändert.

...
...
for /f "tokens=1* delims=_" %%i in ('dir /b /a-d *_*.* 2^>nul') do (  
for /d %%a in ("%Ziel%\%%i -*") do (   
echo %%~fa 
dir /b /a-d "%%a" 2>nul   
echo\ 
)
)>>"%Prot%"  
....
Klappt soweit ganz gut. Hat nur einen Nachteil: da die Dateien mit dem gekürzten Namen (z.B. 1000 oder 1010) x mal vorkommen, wird auch der Pfad im Protokoll x-mal ausgegeben.

Gibt es eine Anweisung, mit der man das Ergebnis in %%i eindeutig machen kann, daß also die Dateinamen nur 1x vorkommen?

Vielen Dank im voraus.

Grüße, MAPL

[Edit Biber] Codetags [/Edit]
Member: bastla
bastla Nov 06, 2010 at 17:19:13 (UTC)
Goto Top
Hallo mapl99sb!
Gibt es eine Anweisung, mit der man das Ergebnis in %%i eindeutig machen kann, daß also die Dateinamen nur 1x vorkommen?
Gibt es so nicht, da ja jede Datei "betrachtet" werden muss und sich %%i aus der Zerlegung des jeweiligen Dateinamens ergibt.

Es könnte aber (ungetestet) etwa so gehen:
set "Liste=%temp%\Liste.txt"  
copy nul "%Liste%"  
for /f "tokens=1* delims=_" %%i in ('dir /b /a-d *_*.* 2^>nul') do findstr "%%i" "%Liste%" || (  
    >>"%Liste%" echo %%i  
    for /d %%a in ("%Ziel%\%%i -*") do (  
    echo %%~fa
    dir /b /a-d "%%a" 2>nul  
    echo\
    )>>"%Prot%"  
)
Grüße
bastla
Member: mapl99sb
mapl99sb Nov 06, 2010 at 22:14:35 (UTC)
Goto Top
Klappt, super !!!!

Vielen Dank nochmals.

Grüsse, MAPL
Member: mapl99sb
mapl99sb Sep 06, 2013 updated at 07:55:30 (UTC)
Goto Top
Hallo,
habe noch eine weitere Anforderung zu dem Programm: und zwar soll es im Zielverzeichnis noch einen Pfad mit gleichem Namen anlegen, in den dann das File kopiert wird. Aber nur, wenn es den Pfad noch nicht gibt. Ansonsten sollen die Files wie bisher in die bestehenden Pfade kopiert werden, also in die, für die ein Match existiert zwischen Datei- und Padnamen.

Also ergänzend zum Beispiel oben:

Wenn zusätzlich eine Datei 3000_a.png existiert, im Zielverzeichnis aber kein Pfad, der mit 3000 beginnt, dann soll der Pfad d:\test\3000 angelegt werden und anschließend das File 3000_a.png dort hinein kopiert werden.

Wie und wo muss ich das in das Coding einsetzen?

Vielen Dank.

Hier mein aktuelles Coding:

@echo off & setlocal
set "Quelle=c:\Temp\Test"
set "Ziel=d:\Test"
set "Prot=%Quelle%\Prot_%date:~-4%-%date:~-7,2%-%date:~-10,2%_%time:~,2%%time:~3,2%%time:~6,2%.txt"
set "Prot=%Prot: =0%"

del "%Prot%" 2>nul
pushd "%Quelle%"
for /f "tokens=1* delims=_" %%i in ('dir /b /a-d e*_*.* 2^>nul') do (
set "Done="
for /d %%a in ("%Ziel%\%%i*") do if not defined Done (
copy "%%i_%%j" "%%a" >nul
set "Done=True"
)
)
popd

set "Liste=%Quelle%\Liste.txt"
copy nul "%Liste%"

"%Liste%" echo %%i

for /d %%a in ("%Ziel%\%%i*") do (
echo %%~fa
dir /b /a-d "%%a" 2>nul
echo\
)
)>>"%Prot%"
Member: kontext
kontext Sep 06, 2013 updated at 08:13:39 (UTC)
Goto Top
Moin @mapl99sb,

bitte erstelle eine neue Frage.
Dieser Thread ist ja mittlerweile doch schon in die Jahre gekommen (und die Grundfrage ist ja gelöst) ...
... du kannst bei der neuen Frage gerne auf diese verlinken ...
... bitte beachte die Formatierungshilfe (FAQ) - vor allem die Code-Formatierung

Gruß
@kontext (Mod)