the-jay
Goto Top

Kopieren und aufteilen von Dateien anhand einer Dateiliste

Hallo,

ich sollte folgendes Problem lösen. Vorliegend ist eine Dateiliste mit ca 20.000 Zeilen die absoluten Pfad und Dateiname enthalten.

Bsp: \\192.168.0.1\Ablage\...\Projekt 1\Datei1.xyz

Die einzelnen Dateien möchte ich nun von verschiedenen Ablageorten an einen Ort kopieren. Dabei sollten Sie zu 100-Datei großen Paketen in entsprechende Unterverzeichnisse aufgeteilt werden.

Mein erster Ansatz wäre ne Batch gewesen die wie folgt ausgesehen hätte.


@echo off
cd\
cd "c:\xyz\"
md 000
copy "\\192.168.0.1\Ablage\...\Projekt 1\Datei1.xyz" "c:\xyz\000"
rem (das ganze dann mit den nächsten 99 Dateien entsprechend)

md 001
copy "\\192.168.0.1\Ablage\...\Projekt 1\Datei101.xyz" "c:\xyz\000"
rem (das ganze dann mit den nächsten 99 Dateien entsprechend)


Nachdem das kopieren nicht den gewünschten Erfolgt erbracht hatte, habe ich die einzelnen Befehle in der Befehlszeile und in der Eingabeaufforderung probiert, dort funktionierte das Kopieren der einzelnen Dateien wunderbar. Aber wenn ich dann 100 Dateien über die Batch versuche zu kopieren, klappts wieder nicht.

Bsp:
@echo off
copy "\\192.168.0.1\Ablage\...\Projekt 1\Datei1.xyz" "c:\xyz\000"
copy "\\192.168.0.1\Ablage\...\Projekt 1\Datei2.xyz" "c:\xyz\000"
copy "\\192.168.0.1\Ablage\...\Projekt 1\Datei3.xyz" "c:\xyz\000"
...
copy "\\192.168.0.1\Ablage\...\Projekt 1\Datei4.xyz" "c:\xyz\000"


Wo liegt das Problem? Welchen schöneren Ansatz gäbe es? Immerhin hätte ich ne filelist.txt mit allen Einträgen.

Danke schon ma

Content-ID: 89992

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

Ausgedruckt am: 26.11.2024 um 18:11 Uhr

bastla
bastla 17.06.2008 um 10:48:22 Uhr
Goto Top
Hallo tHe-jAy und willkommen im Forum!

Das könnte (ungetestet) so gehen:
@echo off & setlocal
set "Liste=D:\Deine Liste.txt"  
set "Ziel=C:\xyz"  
set /a Anzahl=100

set /a OrdnerNr=999
set /a DateiNr=%Anzahl%

for /f "usebackq delims=" %%i in ("%Liste%") do call :ProcessFile "%%i"  
goto :eof

:ProcessFile
if %DateiNr% lss %Anzahl% goto :Kopieren
set /a DateiNr=0
set /a OrdnerNr+=1
if not exist "%Ziel%\%OrdnerNr:~-3%" md "%Ziel%\%OrdnerNr:~-3%"  

:Kopieren
set /a DateiNr+=1
copy %1 "%Ziel%\%OrdnerNr:~-3%\" >nul  
goto :eof
Sollte übrigens eine gleichnamige Datei im Zielordner bereits existieren, wird diese kommentarlos überschrieben.

Grüße
bastla

[Edit] Variablennamen %DateiNr% und %OrdnerNr% vereinheitlicht [/Edit]
tHe-jAy
tHe-jAy 17.06.2008 um 12:20:46 Uhr
Goto Top
Vielen Dank für die schnelle antwort. Hab das auf die schnelle mal ausprobiert (entsprechendes angepasst), leider jedoch ohne erfolg. Der Inhalt übersteigt momentan auch noch mein Wissen, aber ich werde versuchen mich mal komplett durchzuarbeiten. Vorstellen kann ich mir schon was wann wo realisiert wird, trotzdem möcht ichs auch ganz verstehen ;)

Im Moment sieht es leider so aus, dass die Liste nicht verarbeitet wird. Zu Testzwecken hab ich mir ne kleiner Filelist erstellt (auch alles Lokal) aber leider trotzdem ohne Erfolg.

Vielleicht später näheres wenn ich Zeit gefunden hab mich durch den Code zu arbeiten.


mfg
tHe-jAy
tHe-jAy 25.06.2008 um 12:49:07 Uhr
Goto Top
Leider passiert nichts, auch nicht nach mehrmaligem testen.

@echo off & setlocal
set "Liste=C:\Temp\filelist1.txt"  
set "Ziel=C:\Temp\Daten"  
set /a Anzahl=2

set /a OrdnerNr=999
set /a DateiNr=%Anzahl%

for /f "usebackq delims=" %%i in ("%Liste%") do call :ProcessFile "%%i"  
goto :eof

:ProcessFile
if %DateiNr% lss %Anzahl% goto :Kopieren
set /a DateiNr=0
set /a OrdnerNr+=1
if not exist "%Ziel%\%OrdnerNr:~-3%" md "%Ziel%\%OrdnerNr:~-3%"  

:Kopieren
set /a DateiNr+=1
copy %1 "%Ziel%\%OrdnerNr:~-3%\" >nul  
goto :eof


der Inhalt der filelist1.txt sieht wie folgt aus:

"C:\Temp\files\01.txt"  
"C:\Temp\files\02.txt"  
"C:\Temp\files\03.txt"  
"C:\Temp\files\04.txt"  


angezeigt wird folgendes bei "@echo on":
C:\Temp>set "Liste=C:\Temp\filelist1.txt"  
C:\Temp>set "Ziel=C:\Temp\Daten"  
C:\Temp>set /a Anzahl=2

C:\Temp>set /a OrdnerNr=999
C:\Temp>set /a DateiNr=%Anzahl%

C:\Temp>for /f "usebackq delims=" %i in ("C:\Temp\filelist1.txt") do call :ProcessFile "%i"  
C:\Temp>goto :eof

Mach ich nu irgendwas falsch oder steh ich total aufm schlauch? face-sad
bastla
bastla 25.06.2008 um 14:27:58 Uhr
Goto Top
Hallo tHe-jAy!

Bei mir sieht das (mit Deinem Beispiel oben, aber mit "@echo off") so aus:
C:\temp>dir /s /b
C:\temp\filelist1.txt
C:\temp\files
C:\temp\Verteilen.cmd
C:\temp\files\01.txt
C:\temp\files\02.txt
C:\temp\files\03.txt
C:\temp\files\04.txt

C:\temp>type filelist1.txt
"C:\Temp\files\01.txt"  
"C:\Temp\files\02.txt"  
"C:\Temp\files\03.txt"  
"C:\Temp\files\04.txt"  
C:\temp>type Verteilen.cmd
@echo off & setlocal
set "Liste=C:\Temp\filelist1.txt"  
set "Ziel=C:\Temp\Daten"  
set /a Anzahl=2

set /a OrdnerNr=999
set /a DateiNr=%Anzahl%

for /f "usebackq delims=" %%i in ("%Liste%") do call :ProcessFile "%%i"  
goto :eof

:ProcessFile
if %DateiNr% lss %Anzahl% goto :Kopieren
set /a DateiNr=0
set /a OrdnerNr+=1
if not exist "%Ziel%\%OrdnerNr:~-3%" md "%Ziel%\%OrdnerNr:~-3%"  

:Kopieren
set /a DateiNr+=1
copy %1 "%Ziel%\%OrdnerNr:~-3%\" >nul  
goto :eof
C:\temp>verteilen

C:\temp>dir /s /b
C:\temp\Daten
C:\temp\filelist1.txt
C:\temp\files
C:\temp\Verteilen.cmd
C:\temp\Daten\000
C:\temp\Daten\001
C:\temp\Daten\000\01.txt
C:\temp\Daten\000\02.txt
C:\temp\Daten\001\03.txt
C:\temp\Daten\001\04.txt
C:\temp\files\01.txt
C:\temp\files\02.txt
C:\temp\files\03.txt
C:\temp\files\04.txt

C:\temp>
Mit eingeschaltetem "echo":
C:\temp>set "Liste=C:\Temp\filelist1.txt"   

C:\temp>set "Ziel=C:\Temp\Daten"   

C:\temp>set /a Anzahl=2 

C:\temp>set /a OrdnerNr=999 

C:\temp>set /a DateiNr=2 

C:\temp>for /F "usebackq delims=" %i in ("C:\Temp\filelist1.txt") do call :ProcessFile "%i"   

C:\temp>call :ProcessFile ""C:\Temp\files\01.txt""   

C:\temp>if 2 LSS 2 goto :Kopieren 

C:\temp>set /a DateiNr=0 

C:\temp>set /a OrdnerNr+=1 

C:\temp>if not exist "C:\Temp\Daten\000" md "C:\Temp\Daten\000"   

C:\temp>set /a DateiNr+=1 

C:\temp>copy ""C:\Temp\files\01.txt"" "C:\Temp\Daten\000\"  1>nul   

C:\temp>goto :eof 

C:\temp>call :ProcessFile ""C:\Temp\files\02.txt""   

C:\temp>if 1 LSS 2 goto :Kopieren 

C:\temp>set /a DateiNr+=1 

C:\temp>copy ""C:\Temp\files\02.txt"" "C:\Temp\Daten\000\"  1>nul   

C:\temp>goto :eof 

C:\temp>call :ProcessFile ""C:\Temp\files\03.txt""   

C:\temp>if 2 LSS 2 goto :Kopieren 

C:\temp>set /a DateiNr=0 

C:\temp>set /a OrdnerNr+=1 

C:\temp>if not exist "C:\Temp\Daten\001" md "C:\Temp\Daten\001"   

C:\temp>set /a DateiNr+=1 

C:\temp>copy ""C:\Temp\files\03.txt"" "C:\Temp\Daten\001\"  1>nul   

C:\temp>goto :eof 

C:\temp>call :ProcessFile ""C:\Temp\files\04.txt""   

C:\temp>if 1 LSS 2 goto :Kopieren 

C:\temp>set /a DateiNr+=1 

C:\temp>copy ""C:\Temp\files\04.txt"" "C:\Temp\Daten\001\"  1>nul   

C:\temp>goto :eof 

C:\temp>goto :eof 
Wie zu erkennen, stören auch die doppelten Anführungszeichen nicht. Um diese aber dennoch zu vermeiden:
for /f "usebackq delims=" %%i in ("%Liste%") do call :ProcessFile "%%~i"  
Das Problem scheint Deine Liste zu sein - diese wird zwar gefunden (ansonsten bekämst Du eine entsprechende Fehlermeldung), es werden aber keine Inhalte gelesen; eine Begründung dafür kann ich allerdings auch nicht bieten. face-sad

Was mich etwas irritiert, ist die Zeile 6 Deiner "echo"-Zeilen
C:\Temp>set /a DateiNr=%Anzahl% 
%Anzahl% sollte eigentlich zu "2" aufgelöst werden (siehe bei mir Zeile 9).

Grüße
bastla
tHe-jAy
tHe-jAy 26.06.2008 um 11:51:54 Uhr
Goto Top
Hallo Bastla,

nach ein paar mehr Versuchen hat es nun geklappt. So wie es aussieht liegt es daran, das meine originale Filelist als Unicode-Format gespeichert ist. Im ANSI-Format bzw. UTF-8-Format funktioniert es tadellos.

Wäre dies die Erklärung? Falls dies so ist, hab ich ein Problem mit Dateinamen, die Umlaute o.ä. enthalten, denn diese werden nicht korrekt verarbeitet.


Ansonsten wie gesagt, funktioniert es tadellos. Dafür auch herzlichen Dank
bastla
bastla 26.06.2008 um 12:05:59 Uhr
Goto Top
Hallo tHe-jAy!

... Unicode-Format ... Wäre dies die Erklärung?
Zumindest hätte ich keine bessere Idee ...

... Problem mit Dateinamen, die Umlaute o.ä. enthalten
Versuch es mit folgendem Ersatz für die Zeile 9:
for /f "tokens=2 delims=:." %%i in ('chcp') do set "cp=%%i"  
chcp 1252>nul
for /f "usebackq delims=" %%i in ("%Liste%") do call :ProcessFile "%%i"   
chcp %cp%>nul
Damit wird die aktuelle Codepage (zB 850) ausgelesen und zwischengespeichert, dann auf CP 1252 gewechselt, und nach der Verarbeitung wieder der ursprüngliche Wert gesetzt.

Falls das noch nicht genügen sollte, dann vielleicht noch diese Variante (ebenfalls als Ersatz der - einzelnen - Zeile 9):
for /f "tokens=2 delims=:." %%i in ('chcp') do set "cp=%%i"  
type "%Liste%">%temp%\Liste.txt  
chcp 1252>nul
for /f "usebackq delims=" %%i in ("%temp%\Liste.txt") do call :ProcessFile "%%i"  
del %temp%\Liste.txt
chcp %cp%>nul

Grüße
bastla
tHe-jAy
tHe-jAy 26.06.2008 um 12:51:52 Uhr
Goto Top
Was soll ich jetzt noch sagen... außer

@echo off
cls
echo.
echo.
echo.
echo.
echo                  Vielen herzlichen Danke
echo                  fr die perfekte Hilfe!
echo.
echo.
echo.
echo.
pause
exit