thunderbolt78
Goto Top

Per Batch bestimmte anzahl von dateien verschieben und ordner anlegen

Hi,

folgende Ausgangsituation,

über den Tag verteilt landen in einem bestimmten Ordner der User Dateien mit unterschiedlichen Dateinnamen und Endungen

Struktur

user1\project1\results
user1\project2\results
user1\daten1\results

user2\test123\results
user2\wasweisich\results

user3 ....
user3 .....

in diesen results Ordnern landen manchmal bis zu 15000 dateien, welchen über ftp auf unseren Webspace hochgeladen werden.

gibt es eine möglichkeit innerhalb der Ordner project1 oder project2 unterordner anzulegen wo maximale 400 oder 500 dateien drin sind

user1\project1\results
user1\project1\results1-400
user1\project1\results400-500
user1\project2\results
user1\project2\results1-400
user1\daten1\results
user1\daten1\results1-400
user1\daten1\results400-500
user1\daten1\results500-1000

user2\test123\results
user2\wasweisich\results

user3 ....
user3 .....

es geht halt darum das resultsverzeichniss mit den massig dateien auf mehrere kleinere zu verteilen. geht sowas überhaupt ?

lg thunderbolt

Content-Key: 202585

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

Printed on: April 19, 2024 at 15:04 o'clock

Member: bastla
bastla Feb 28, 2013 updated at 22:31:43 (UTC)
Goto Top
Hallo thunderbolt78 und willkommen im Forum!

Das könnte etwa so gehen:
@echo off & setlocal
set "Basis=D:\Testordner"  
set "Ordner=results"  
set "Anzahl=400"  

for /f "delims=" %%i in ('dir /s/b/ad "%Basis%\%Ordner%"') do call :ProcessDir "%%i"  
goto :eof

:ProcessDir
echo Bearbeite %1
pushd %1
set /a Nr=0
set /a Bis=0
set /a Z=0

for /f "delims=" %%a in ('dir /b/a-d 2^>nul') do call :ProcessFile "%%a"  
popd
echo #################################
goto :eof

:ProcessFile
set /a Z+=1
if %Z% leq %Bis% goto :MoveIt
set /a Nr+=1
set /a Von=(Nr-1)*Anzahl+1
set /a Bis=Nr*Anzahl
set /a Z=Von
set Verz=..\%Ordner%%Von%-%Bis%
echo md %Verz%
:MoveIt
echo move %1 %Verz%
goto :eof
Soll der Basisordner (unter dem die einzelnen "user#"-Ordner liegen) in Zeile 2 ein Root-Verzeichnis (wie etwa "D:\") sein, muss er ohne abschließenden "\" angegeben werden - also:
set "Basis=D:"
Wegen des "echo" am Beginn der Zeilen 29 und 31 wird der gesamte Ablauf nur simuliert - wenn das Ergebnis vernünftig aussieht, einfach beide entfernen und machen lassen ...

Um sich das Ergebnis der Simulation in Ruhe ansehen zu können, den Batch (gespeichert zB als "D:\Aufteilen.cmd") aus einem CMD-Fenster starten und die Ausgaben in eine Datei schreiben lassen - im Beispiel etwa:
D:\Aufteilen.cmd>D:\Ergebnis.txt
Wenn die Dateien tatsächlich verschoben werden, bleiben die ursprünglichen "results"-Ordner erhalten, sollten allerdings jeweils leer sein.

Grüße
bastla
Member: thunderbolt78
thunderbolt78 Feb 28, 2013 at 22:51:51 (UTC)
Goto Top
alter schwede das ging ja schnell ... ich probiere das morgen sofort aus. Wo muss ich die bat datein hinkopieren, bei jedem user einzeln ? oder reicht es übergeordnet.
Member: bastla
bastla Feb 28, 2013 at 22:59:04 (UTC)
Goto Top
Hallo thunderbolt78!

Den Batch kannst Du (fast) beliebig platzieren (in einem "results"-Ordner selbst wäre suboptimal face-wink) - es werden immer alle unterhalb des angegebenen Basis-Ordners befindlichen "results"-Ordner erfasst (also für alle User en bloc) - allerdings wird nicht auf die Ordnertiefe geachtet, sodass auch ein Ordner "User1\Test1\Untertest1\Unteruntertest1\results" verarbeitet wird.

Grüße
bastla
Member: thunderbolt78
thunderbolt78 Feb 28, 2013 at 23:05:18 (UTC)
Goto Top
als kleines schmanklerl würde`ich mir noch wünschen, dass die results 1-399, results 400-799 in einen anderes verzeichnis mit

original

arbeitsverzeichnis\user1\project1\results (1000) dateien
arbeitsverzeichnis\user1\project2\results (2000) dateien
arbeitsverzeichnis\user1\daten1\results (4000) datein

umbewegt

backup\user1\project1\results1-399
backup\user1\project1\results400-799 usw.

backup\user1\project2\results1-399
backup\user1\project2\results400-799 usw.
backup\user1\daten1\results usw.

landen.
Member: bastla
bastla Feb 28, 2013 at 23:25:54 (UTC)
Goto Top
Hallo thunderbolt78!

Sollten Deine Ordner tatsächlich nicht "results", sondern zB "results (1000) dateien" heißen, kann mein Ansatz so natürlich nicht funktionieren, da nur "results" als Ordnername gesucht wird - wenn alle Ordner, deren Name nur mit "results" beginnt, gefragt wären, müsstest Du

Zeile 3 durch
set "Ordner=results*"
und Zeile 28 durch
set Verz=..\results%Von%-%Bis%
ersetzen - wenn denn die neuen Ordner konstant mit "resultsVon-Bis" benannt werden sollen.

Grüße
bastla
Member: thunderbolt78
thunderbolt78 Feb 28, 2013 at 23:35:58 (UTC)
Goto Top
Nein die ordner heissen immer results. Die zahl sollte nur zeigen, dass da 1000 dateien drin sind.
Member: bastla
bastla Feb 28, 2013 updated at 23:50:19 (UTC)
Goto Top
Hallo thunderbolt78!

Ok - mit geändertem Basispfad für die neuen Ordner sähe das eher so aus:
@echo off & setlocal
set "Quelle=D:\Testordner"  
set "Ordner=results"  
set "Ziel=D:\Backup"  
set "Anzahl=400"  

for /f "delims=" %%i in ('dir /s/b/ad "%Quelle%\%Ordner%"') do call :ProcessDir "%%i"  
goto :eof

:ProcessDir
echo Bearbeite %1
pushd %1
set "QuellPfad=%~dp1"  
call set "ZielPfad=%%QuellPfad:%Quelle%=%Ziel%%%"  

set /a Nr=0
set /a Bis=0
set /a Z=0

for /f "delims=" %%a in ('dir /b/a-d 2^>nul') do call :ProcessFile "%%a"  
popd
echo #################################
goto :eof

:ProcessFile
set /a Z+=1
if %Z% leq %Bis% goto :MoveIt
set /a Nr+=1
set /a Von=(Nr-1)*Anzahl+1
set /a Bis=Nr*Anzahl
set /a Z=Von
set "Verz=%ZielPfad%%Ordner%%Von%-%Bis%  
echo md %Verz%
:MoveIt
echo move %1 %Verz%
goto :eof
Grüße
bastla
Member: thunderbolt78
thunderbolt78 Mar 01, 2013 updated at 15:57:38 (UTC)
Goto Top
habe es grade mal probiert, aber leider tut sich da nix, in dem results ordner liegen ca. 100 Dateien, kommt keine Fehlermeldung nix, egal wie oft ich die cmd aufrufe. Ich habe ein Programm, welches bei jedem neuerstellen einer datei in dem results ordner diese cmd aufruft.

@echo off & setlocal
set "Quelle=c:\Intel"
set "Ordner=results"
set "Ziel=c:\Backup"
set "Anzahl=4"

for /f "delims=" %%i in ('dir /s/b/ad "%Quelle%\%Ordner%"') do call :ProcessDir "%%i"
goto :eof

:ProcessDir
echo Bearbeite %1
pushd %1
set "QuellPfad=%~dp1"
call set "ZielPfad=%%QuellPfad:%Quelle%=%Ziel%%%"

set /a Nr=0
set /a Bis=0
set /a Z=0

for /f "delims=" %%a in ('dir /b/a-d 2^>nul') do call :ProcessFile "%%a"
popd
echo #################################
goto :eof

:ProcessFile
set /a Z+=1
if %Z% leq %Bis% goto :MoveIt
set /a Nr+=1
set /a Von=(Nr-1)*Anzahl+1
set /a Bis=Nr*Anzahl
set /a Z=Von
set "Verz=%ZielPfad%%Ordner%%Von%-%Bis%
md %Verz%
:MoveIt
move %1 %Verz%
goto :eof
Member: bastla
bastla Mar 01, 2013 at 16:07:13 (UTC)
Goto Top
Hallo thunderbolt78!

Versuch es nochmal mit folgenden Zeilen 33 bis 36:
md "%Verz%" 2>nul  
:MoveIt
move %1 "%Verz%"  
goto :eof
Es sollte auf jeden Fall eine Anzeige des/der Quellordner/s in der Art
Bearbeite "C:\Intel\user1\project1\results"
#################################
erfolgen - falls Du nicht aus der CMD-Shell (sondern per Doppelklick) testest, könntest Du zwischen Zeile 7 und 8 eine Zeile
pause
einfügen.

Wenn es noch immer nicht funktionieren sollte, ändere "echo off" auf "echo on" und sieh Dir den Ablauf des Batches in seinen Einzelheiten an ...

Grüße
bastla

P.S.: Verwende zum Posten von Code bitte die passende Formatierung.
Member: thunderbolt78
thunderbolt78 Mar 01, 2013 at 16:27:07 (UTC)
Goto Top
habe es wie oben abgeändert leider keinen Erfolg, das Backup Verzeichniss bleibt leer

Ergebniss txt habe ich das, aber nur wenn ich oben echo on einstelle

C:\Intel>set "Quelle=c:\Intel"   

C:\Intel>set "Ordner=results"   

C:\Intel>set "Ziel=c:\Backup"   

C:\Intel>set "Anzahl=4"   

C:\Intel>for /F "delims=" %i in ('dir /s/b/ad "c:\Intel\results"') do call :ProcessDir "%i"   

C:\Intel>goto :eof 
Member: thunderbolt78
thunderbolt78 Mar 01, 2013 updated at 18:06:38 (UTC)
Goto Top
jawoll es klappt ....

ich musste die cmd aus dem verzeichniss rausnehmen und ein verzeichniss höher anwenden

wie kann ich dir dafür danken ?

wäre es noch möglich nen befehl dranzuhängen die enstandenen Ordner gleich zu zippen oder zu raren, sobald die voll mit 400 Dateien sind ?

1 schönheitsfehler habe ich noch,

ich kopiere die dateien bevor das cmd läuft komplett. Sicher ist sicher wenn er mit dem kopieren fertig ist, bleiben die leeren ordner zurück, kann man die auch fix mit löschen ?

wenn der user 1 Projekt beendet hat und ein neues beginnt, bleiben von dem vorherigen Project die Ordner bestehen und werden dann beim nächsten cmd durchlauf wieder miterstellt und ich habe dann

User1\project1\results\results1-400 der leer ist obwohl der user schon bei projekt2 oder oder 3 ist. vielleicht kann man es so hinerlegen, dass leere verzeichnisse nicht berücksichtigt werden.

vielen Dank nochmal
Member: bastla
bastla Mar 02, 2013 updated at 15:12:41 (UTC)
Goto Top
Hallo thunderbolt78!
User1\project1\results\results1-400
sollte überhaupt nicht entstehen, da ja für das Festlegen des Zielpfades nur der Teil "User1\project1\" verwendet wird (siehe Zeile 13) ...

Damit auch der (wenn alles geklappt hat) leere Ordner "results" entfernt wird, kannst Du die folgende ergänzte Version testen - in den Zeilen 22 und 30 könntest Du dann auch noch die Befehlszeile (in beiden Zeilen ist die gleiche Zeile zu verwenden) des von Dir verwendeten Packers (zip, rar) platzieren ...
@echo off & setlocal
set "Quelle=C:\Intel"  
set "Ordner=results"  
set "Ziel=C:\Backup"  
set "Anzahl=4"  

for /f "delims=" %%i in ('dir /s/b/ad "%Quelle%\%Ordner%"') do call :ProcessDir "%%i"  
goto :eof

:ProcessDir
echo Bearbeite %1
pushd %1
set "QuellPfad=%~dp1"  
call set "ZielPfad=%%QuellPfad:%Quelle%=%Ziel%%%"  
set "Verz="  

set /a Nr=0
set /a Bis=0
set /a Z=0

for /f "delims=" %%a in ('dir /b/a-d 2^>nul') do call :ProcessFile "%%a"  
popd
if defined Verz REM hier Befehl zum zippen des Ordners %Verz%
rd %1 2>nul
echo #################################
goto :eof

:ProcessFile
set /a Z+=1
if %Z% leq %Bis% goto :MoveIt
if defined Verz REM hier Befehl zum zippen des Ordners %Verz%
set /a Nr+=1
set /a Von=(Nr-1)*Anzahl+1
set /a Bis=Nr*Anzahl
set /a Z=Von
set "Verz=%ZielPfad%%Ordner%%Von%-%Bis%  
md "%Verz%"  
:MoveIt
move %1 "%Verz%"  
goto :eof
Grüße
bastla

[Edit] Zeile 15 hinzugefügt, Zeilen 23 und 31 ergänzt (siehe unten) [/Edit]
Member: thunderbolt78
thunderbolt78 Mar 02, 2013 updated at 14:11:05 (UTC)
Goto Top
werde es gleich probieren, da ich fast überhaupt keine Ahnung habe, warum ist 2x der packer dazugeschaltet ?

okay funktioniert einwandfrei so wie ich es will. Vielen vielen Dank. Ich wusste gar nicht, dass batch dateien so mächtig sind.
Member: bastla
bastla Mar 02, 2013 updated at 15:11:37 (UTC)
Goto Top
Hallo thunderbolt78!

Ich habe oben noch Zeile 15 hinzugefügt und die "Packer"-Zeilen so ergänzt, dass nur gepackt wird, wenn es auch bereits einen Zielordner gibt.

Der Aufruf in Zeile 31 startet das Packen bevor ein neuer Zielordner erstellt wird - dann ist der vorherige nämlich voll.
Wenn der letzte Ordner voll ist, wird die Zeile 31 nicht mehr erreicht - daher das Packen dieses Ordners in Zeile 23.

Grüße
bastla
Member: thunderbolt78
thunderbolt78 Mar 03, 2013 updated at 12:42:25 (UTC)
Goto Top
Hi Bastla,

ich habe die Batch nun in einer Lifeumgebung laufen. Leider funktioniert es nicht richtig. Es ist so, dass alle sagen wir mal 3 bis 4 Minuten eine Datei in dem Ordner Quelle=C:\Intel\results erstellt wird. Alle 10 Minuten läuft die Batch Datei. Der Ordner wird alle 10 Minuten entleert und es wird sofern sich 40 Dateien darin befinden 2 ordner mit Namen results 1-40 und results 41-80 angelegt. Soweit so gut.

Nun kommt es vor, dass nur alle 15 Minuten eine Datei in den results Ordner geschrieben wird, weil die User 10-15 Minuten pro datei rechnen. Es wird wieder alle 10 Minuten die cmd ausgeführt aber diesmal werden halt nur 1 oder Dateien in den Results1-40 kopiert. Nach mehreren Stunden, habe ich einen Ordner results 1-20 der ca. 2000 Dateien hat, warscheinlich weil zum Zeitpunkt des kopierens keine 40 Dateien zum Zählen zur Verfügung standen. Ist das einfach zu lösen ?
Member: bastla
bastla Mar 03, 2013 at 12:55:21 (UTC)
Goto Top
Hallo thunderbolt78!

Bevor ich (später) anfange, mir Gedanken darüber zu machen: Hat Deine Lifveumgebung noch mehr Überraschungen zu bieten?

Grüße
bastla
Member: thunderbolt78
thunderbolt78 Mar 03, 2013 at 13:19:05 (UTC)
Goto Top
Hallo bastla,

Sry ich habe es bisher nur mit fertigen ordnern gestestet wo alle dateien schon komplett fertig drinliegen. Jetzt in der liveumgebung werden die dateien erstellt. Mal sind es 100 in 10 minuten und ein project spaeter sind es nur 2 dateien pro stunde. Wenn du skype hast kann ich dir das gerne erklaeren oder auch zeigen.
Member: bastla
bastla Mar 03, 2013 updated at 20:45:31 (UTC)
Goto Top
Hallo thunderbolt78!

Ich hoffe, meine Fantasie hat auch genügt ...

Teste mal mit
@echo off & setlocal
set "Quelle=C:\Intel"  
set "Ordner=results"  
set "Ziel=C:\Backup"  
set "Anzahl=40"  

for /f "delims=" %%i in ('dir /s/b/ad "%Quelle%\%Ordner%" 2^>nul') do call :ProcessDir "%%i"  
goto :eof

:ProcessDir
echo Bearbeite %1
pushd %1
set "QuellPfad=%~dp1"  
call set "ZielPfad=%%QuellPfad:%Quelle%=%Ziel%%%"  
set "Verz="  

set /a Nr=0
set /a Bis=0
set /a Z=0

for /f "delims=" %%a in ('dir /b/a-d 2^>nul') do call :ProcessFile "%%a"  
popd
if defined Verz REM hier Befehl zum zippen des Ordners %Verz%
rd %1 2>nul
echo #################################
goto :eof

:ProcessFile
set /a Z+=1
if %Z% leq %Bis% goto :MoveIt
if defined Verz REM hier Befehl zum zippen des Ordners %Verz%
set /a Nr+=1
set /a Von=(Nr-1)*Anzahl+1
set /a Bis=Nr*Anzahl
set "Verz=%ZielPfad%%Ordner%%Von%-%Bis%  
md "%Verz%" 2>nul  
for /f %%i in ('dir "%Verz%" 2^>nul^|findstr "Datei(en)"') do set /a Z=Von+%%i  
if %Z% gtr %Bis% (set /a Z=%Bis% & goto :ProcessFile)
:MoveIt
move %1 "%Verz%"  
goto :eof
Offen bleibt für mich die Frage des Komprimierens: Es werden ja jetzt bestehende Ordner, die voll sind, zwar nicht weiter befüllt - das Packen in Zeile 31 würde aber trotzdem erfolgen. Mit einer Überprüfung (per "if exist") ließe sich zwar das neuerliche Erstellen des ZIP-Files verhindern, allerdings würden dann Dateien, mit denen vorher noch nicht ganz volle Ordner aufgefüllt wurden, durch den Rost fallen ...

Ach ja, noch etwas: "move" überschreibt kommentarlos bereits im Zielordner vorhandene gleichnamige Dateien.

Grüße
bastla
Member: thunderbolt78
thunderbolt78 Mar 03, 2013 at 22:05:28 (UTC)
Goto Top
Hallo Bastla,

vielen Dank, dass du dir die Zeit nimmst. Derzeit habe ich den zipper noch nicht eingeschaltet, aber mit dem neuen Script funktioiert es nicht,

ich habe 39 Dateien in den Ordner intel\results kopiert, den batch laufen lassen und es wurde ein Ordner results1-40 erstellt mit den 39 dateien, dann habe ich wieder 39 Dateien in den intel\results kopiert, den batch wieder laufen lassen und es befanden sich 78 Dateien in dem results1-40 Ordner.

mit
>nul^|findstr "Datei(en)"')  

muss ich dort was eintragen, den string den er finden soll ?
Member: bastla
bastla Mar 03, 2013 updated at 22:22:32 (UTC)
Goto Top
Hallo thunderbolt78!

Der String, der gefunden werden soll, ist "Datei(en)" und daher bereits eingetragen - es sei denn, bei Deinem Betriebssystem würde in der vorletzten Zeile eines "dir"-Befehls nicht die Anzahl der darin enthaltenen Dateien im Format
               6 Datei(en)      1.565.096 Bytes
stehen.

Testen könntest Du übrigens auch mit 4 Dateien - das wäre bei einem "echo on" in Zeile 1 etwas leichter nachzuvollziehen ...
Übrigens: Die ursprüngliche Struktur (die ich auch zum Testen verwende) hätte eigentlich unterhalb von "C:\Intel" noch einen "User"-Ordner und erst darin den Ordner "results" enthalten - soll das jetzt tatsächlich anders sein?

Grüße
bastla
Member: thunderbolt78
thunderbolt78 Mar 03, 2013 at 22:25:18 (UTC)
Goto Top
Hi Bastla,

richtig unterhalb des intel Ordners ist noch ein user Ordner, erst dann kommt results. War mein Fehler. Funktioniert das script bei dir ?
Member: bastla
bastla Mar 03, 2013 at 22:29:13 (UTC)
Goto Top
Hallo thunderbolt78!

Bei meinen Tests (auch mit mehreren User-Ordnern) wurde wie gewünscht aufgeteilt/aufgefüllt.

Grüße
bastla
Member: thunderbolt78
thunderbolt78 Mar 03, 2013 updated at 22:33:26 (UTC)
Goto Top
ich habe mal Datei(en) mit File(s) ersetzt..... weist bestimmt warum. Aber leider keine Verbesserung.

ich habe 19 reinkopiert, batch ausgeführt und 19 dateien im results1-20 gefunden, wieder 19 reinkopiert batch ausgeführt und es waren leider 38 drin.
Member: thunderbolt78
thunderbolt78 Mar 03, 2013 at 22:36:56 (UTC)
Goto Top
vergiss alles was ich gesagt habe ....

es muss ja File(s) heissen und nicht Files(s). Es schein nun zu gehen, hast du nen Paypal Konto würde gerne eine spende erbringen.
Member: bastla
bastla Mar 03, 2013 at 22:43:35 (UTC)
Goto Top
Hallo thunderbolt78!
würde gerne eine spende erbringen.
Lass stecken ...

Übrigens: Tu Dir (und jenen, die Dir helfen wollen) einen Gefallen: Beschreibe beim nächsten Mal die Ausgangslage vollständig inkl Angabe des Betriebssystems (und dessen Sprache) ...

Grüße
bastla
Member: thunderbolt78
thunderbolt78 Mar 03, 2013 at 22:54:57 (UTC)
Goto Top
Hallo Bastla,

vielen Dank nochmal. du hast mir damit sehr geholfen. An die Sprache des OS habe ich ja nicht gedacht, ich konnte ja nicht ahnen, dass du den String ausliest. Es hat ja alles funktioniert bis ich es live getestet habe.

vielen Dank

lg Thunderbolt.
Member: cdm1970
cdm1970 Jan 18, 2017 at 20:22:40 (UTC)
Goto Top
Hallo bastla,
ich habe diesen Beitrag gefunden und suche genau das!

Leider face-sad läuft das Batch bei mir nicht ???
Ich weiß daß es gehen muß.
Kannst du bitte das Batch abändern?

Ich hab Windows 7.

Ich habe auf der Festplatte F:\
Ein Ordner mit Namen: Artikel
F:\Artikel

Im Ordner: Artikel
sind 18.000 .html Seiten drin.
Ich wollte jetzt gerne,
immer 1.000 .html Seiten Kopieren und in ein neu erstellten Ordner mit Namen: 1
erstellen lassen.

Im Ordner: 1 sind die ersten 1.000 html Seiten drin.
Im Ordner: 2 sind die nächsten 1.000 html Seiten drin usw.
Bis am Ende 1,2,3….bis 18 Ordner mit jeweils 1.000 html Seite drin sind.

Vielen Dank für deine Hilfe.

Gruß

Carlo