Batch um Dateien nach Anzahl in Ordner abzulegen
Hallo,
ich suche eine Möglichkeit eine Batchdatei in einem Verzeichnis auszuführen in dem eine große Anzahl von kleinen Dateien liegt. Können ein paar Zehntausend sein. Diese Dateien sollen nun alphabetisch nach einer bestimmten Anzahl in Unterordner verpackt werden. Wenn die Anzahl zB 500 wäre dann sollen die ersten 500 Dateien in einen Unterordner der 00500 heißt. Die nachfolgenden in 01000 usw. Pro Datei könnte man das nötige Unterverzeichnis herausfinden indem man zB die Nummer der Datei nimmt die fraglich ist und durch 500 teilt. Davon die Ganzzahl und das wieder mal 500. Dann müsste bei Bedarf nur noch eine Anzahl Nullen davorgesetzt werden damit die Unterordner sortiert sind.
Kann man das mit einer Batch lösen? Ich kenne mich ein wenig damit aus aber nicht so gut um das sagen zu können...
Grüße!
Sebastian
ich suche eine Möglichkeit eine Batchdatei in einem Verzeichnis auszuführen in dem eine große Anzahl von kleinen Dateien liegt. Können ein paar Zehntausend sein. Diese Dateien sollen nun alphabetisch nach einer bestimmten Anzahl in Unterordner verpackt werden. Wenn die Anzahl zB 500 wäre dann sollen die ersten 500 Dateien in einen Unterordner der 00500 heißt. Die nachfolgenden in 01000 usw. Pro Datei könnte man das nötige Unterverzeichnis herausfinden indem man zB die Nummer der Datei nimmt die fraglich ist und durch 500 teilt. Davon die Ganzzahl und das wieder mal 500. Dann müsste bei Bedarf nur noch eine Anzahl Nullen davorgesetzt werden damit die Unterordner sortiert sind.
Kann man das mit einer Batch lösen? Ich kenne mich ein wenig damit aus aber nicht so gut um das sagen zu können...
Grüße!
Sebastian
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 100196
Url: https://administrator.de/forum/batch-um-dateien-nach-anzahl-in-ordner-abzulegen-100196.html
Ausgedruckt am: 23.12.2024 um 07:12 Uhr
9 Kommentare
Neuester Kommentar
Hallo SebastianJu und willkommen im Forum!
Sollte der Dateiname tatsächlich bereits eine laufende Nummer enthalten, wäre es sinnvoll, den Aufbau des Namens darzustellen.
Grüße
bastla
Diese Dateien sollen nun alphabetisch ...
... die Nummer der Datei ...
Wenn die Dateien bereits Nummern haben, wozu dann eine alphabetische Ordnung?... die Nummer der Datei ...
Sollte der Dateiname tatsächlich bereits eine laufende Nummer enthalten, wäre es sinnvoll, den Aufbau des Namens darzustellen.
Grüße
bastla
... unabhängig davon, ob die Nummer erst erzeugt werden muss (davon geht der folgende Ansatz aus) oder bereits vorhanden ist, könnte der Ablauf etwa so aussehen:
Die Stellenanzahl (Stichwort: "führende Nullen") für die Ordnernamen ist derzeit auf 5 gesetzt (siehe Zeile 19), kann aber bei Bedarf auf bis zu 9 erhöht werden.
Grüße
bastla
[Edit] Alphabetische Sortierung ergänzt [/Edit]
[Edit2] Fehlendes "%"-Zeichen in Zeile 15 nachgetragen {/Edit2]
@echo off & setlocal
set "Ordner=D:\Ordner mit vielen Dateien"
set /a Einh=500
set /a Start=1000000000
pushd "%Ordner%"
set /a ONr=%Start%
set /a Nr=0
for /f "delims=" %%i in ('dir /b /a-d /on') do call :ProcessFile "%%i"
popd
goto :eof
:ProcessFile
set /a Chk=%Nr%%%%Einh%
if %Chk% neq 0 goto :MoveFile
set /a ONr+=%Einh%
set Akt=%ONr:~-5%
md %Akt%
:MoveFile
move %1 %Akt%
set /a Nr+=1
goto :eof
Grüße
bastla
[Edit] Alphabetische Sortierung ergänzt [/Edit]
[Edit2] Fehlendes "%"-Zeichen in Zeile 15 nachgetragen {/Edit2]
Moin SebastianJu,
willkommen im Forum.
noch eine kleine Fussnote zu bastlas Lösung.
Wenn Du wirklich ein paar 10000 Dateien bearbeiten willst, dann wäre unter Umständen als Zwischenschritt das Schreiben des DIR-Outputs in eine temporäre Datei performanter.
Also statt
..lieber der Umweg..
Okay, wenn der Batch natürlich die einzige gestartete Anwendung ist und sich die Arbeitsspeicher-Ressourcen mit keinen anderen Prozessen teilen muss, dann ist es egal.
Aber im Normalfall soll dieser Batch ja irgendwo im Hintergrund vor sich hin drömeln, während Du im Vordergrund weiterhin ruckelfrei Videoclips geniesst....
Grüße
Biber
willkommen im Forum.
noch eine kleine Fussnote zu bastlas Lösung.
Wenn Du wirklich ein paar 10000 Dateien bearbeiten willst, dann wäre unter Umständen als Zwischenschritt das Schreiben des DIR-Outputs in eine temporäre Datei performanter.
Also statt
..
for /f "delims=" %%i in ('dir /b /a-d /on') do (
...
..
dir /b /a-d /on>%temp%\dirlist.txt
for /f "delims=" %%i in (%temp%\dirlist.txt) do (
..
)
del %temp%\dirlist.txt
...
Okay, wenn der Batch natürlich die einzige gestartete Anwendung ist und sich die Arbeitsspeicher-Ressourcen mit keinen anderen Prozessen teilen muss, dann ist es egal.
Aber im Normalfall soll dieser Batch ja irgendwo im Hintergrund vor sich hin drömeln, während Du im Vordergrund weiterhin ruckelfrei Videoclips geniesst....
Grüße
Biber
Moin SebastianJu,
bastla ist anscheinend noch inner Disse - deshalb versuche ich mal seine Variante zu kommentieren und auch meine Winz-Änderung einzubauen.
Zusätzlich habe ich vor den beiden eigentlich arbeitenden Befehlen MD und MOVE ein GROSS geschriebenes ECHO gesetzt - so kannst Du den Batch als Simulation durchlaufen lassen und siehst, was passieren würde.
Das müssen wir jetzt einmal tun, um den Fehler bei Dir zu finden.
Poste bitte den Output (bzw. ein paar Zeilen davon).
Grüße
Biber
bastla ist anscheinend noch inner Disse - deshalb versuche ich mal seine Variante zu kommentieren und auch meine Winz-Änderung einzubauen.
@echo off & setlocal
:: Echo der Befehle auf dem Bildscirm AUS
:: setlocal: alle mit SET gesetzten Variablen gelten nur in diesem Batch
set "Ordner=D:\Ein Ordner mit den vielen Dateien"
::Hier anpassen: Dein Ordnername
set /a Einh=500
:: Paketgröße...numerische Variable; 500 Dateien je Ordner
set /a Start=1000000000
:: Hilfvariable, die letzten x Zeichen davon bilden den Verzeichnisnamen
pushd "%Ordner%"
:: Wechseln in das Verzeichnis, in dem die vielen Dateien liegen
:: Und das Verzeichnis merken, von dem Du gestartet bist
set /a ONr=%Start%
set /a Nr=0
:: Zwei weitere numerische Variablen.
:: Was eine 0Nr ist, bekommst Du im Lauf des Lebens alleine raus...*g
dir /b /a-d /on>%temp%\dirlist.txt
:: Komplettinhalt des Verszeichnisses in eine Temp-Datei schreiben
for /f "delims=" %%i in (%temp%\dirlist.txt) do call :ProcessFile "%%i"
:: Für alle Zeilen in der Temp-Datei jeweils die ganze Zeile
:: als Parameter %%i für einen Sub-Block :ProcessFile weiterreichen
:: Wenn Du hier ankommst, sind ALLE Zeilen/ALLE Dateien verarbeitet
del %temp%\dirlist.txt>nul
popd
:: Aufräumarbeiten
goto :eof
:: ~~~Hier ist der Batch zu Ende~~ Unterhalb nur Sub-Routinen
:ProcessFile
set /a Chk=Nr %% Einh
:: Errechne Variable Chk als [Nr modulo Einh];
:: Bsp: 777 mod 500=277
if %Chk% neq 0 goto :MoveFile
:: wenn Chk NICHT 0 ist, weiter zu :MoveFile.
:: Andernfalls sind 500 Dateien im Ordner.
:: Dann hier weiter.
set /a ONr+=%Einh%
:: die Basis für den nächsten Ordnernamen hochzählen
set Akt=%ONr:~-5%
ECHO md %Akt%
:: Von numerischen Wert die letzten 5 Stellen nehmen und Verzeichnis anlegen.
:MoveFile
ECHO move %1 %Akt%
:: nächste Datei verschieben
set /a Nr+=1
:: ...und den Zähler für die max.500 bzw. max %Einh% um 1 erhöhen.
goto :eof
:: hier bedeutet "goto :eof"-->Ende von :Processfile
Zusätzlich habe ich vor den beiden eigentlich arbeitenden Befehlen MD und MOVE ein GROSS geschriebenes ECHO gesetzt - so kannst Du den Batch als Simulation durchlaufen lassen und siehst, was passieren würde.
Das müssen wir jetzt einmal tun, um den Fehler bei Dir zu finden.
Poste bitte den Output (bzw. ein paar Zeilen davon).
Grüße
Biber
@Biber
Danke für die Nachtschicht ...
... und ja, ich kenne die Passage
Dass übrigens %%% anstelle von %% im Batch auch funktionieren kann, ist mir neu - sogar ein
for %%i in (*.txt) do echo %%%i
läuft anstandslos durch ...
@SebastianJu
Jetzt habe ich da oben in Zeile 15 schon so viele "%"-Zeichen verwendet, und dann war's immer noch um eines zu wenig (oder um 3 zuviel ) - ist korrigiert, kann aber nicht der Grund für das "Nicht-Verschieben" gewesen sein, da es sich (weshalb mir beim Testen auch nichts aufgefallen war) nicht weiter ausgewirkt hat (die Verzeichnisse wurden ja auch erstellt).
Mit Bibers Version müsste es aber auf jeden Fall klappen (und wenn Du nach dem erfolgreichen Testen die beiden angesprochenen ECHO entfernst, werden auch tatsächlich Verzeichnisse erstellt und Dateien verschoben).
Grüße
bastla
Danke für die Nachtschicht ...
... und ja, ich kenne die Passage
Somit können Sie mit Umgebungsvariablen Berechnungen vornehmen, ohne %-Zeichen einzugeben ...
aus der Hilfe zu "set" und hatte auch daran gedacht, diese Kurzform zu verwenden, es aber dann "gut gemeint" (was ja nicht ohne Grund als Gegenteil von "gut gemacht" gilt) und trotzdem die Variablenschreibweise wie gewohnt mit %Variable% vorgenommen.Dass übrigens %%% anstelle von %% im Batch auch funktionieren kann, ist mir neu - sogar ein
for %%i in (*.txt) do echo %%%i
läuft anstandslos durch ...
@SebastianJu
Jetzt habe ich da oben in Zeile 15 schon so viele "%"-Zeichen verwendet, und dann war's immer noch um eines zu wenig (oder um 3 zuviel ) - ist korrigiert, kann aber nicht der Grund für das "Nicht-Verschieben" gewesen sein, da es sich (weshalb mir beim Testen auch nichts aufgefallen war) nicht weiter ausgewirkt hat (die Verzeichnisse wurden ja auch erstellt).
Mit Bibers Version müsste es aber auf jeden Fall klappen (und wenn Du nach dem erfolgreichen Testen die beiden angesprochenen ECHO entfernst, werden auch tatsächlich Verzeichnisse erstellt und Dateien verschoben).
Grüße
bastla
Tja SebastianJu,
sieht in der Tat so aus, als hättest Du den bislang undokumentierten M$-Bug No. #138654 gefunden. Eventuell wird der mal nach Dir benannt.
Also, der MOVE-Befehl scheint offensichtliche Probleme mit diesen langen Dateinamen (oder den vielen Leerzeichen im Namen?)" zu haben.
Einfache Verifizierung dieser rufschädigenden Behauptung am CMD-Prompt:
[einzugebende Zeilen beginnen mit ">"]
Anmerkung: der Name der Datei "Zybex -...bla.txt" ist 133 Byte lang und das Verschieben sollte von "D:\temp" nach D:\temp\00500" erfolgen -- also kein erkennbares Limit in der Nähe.
Workaround.
Mach den MOVE-Befehl in zwei Schritten,
Zuerst COPY von A nach B, dann Löschen in A.
Konkret:
STREICHE:
SETZE:
Oder Du benennst diese etwas sperrigen Dateinamen um
-> von: "Zybex - {endloses sinnfreies Reklamegelumpe}.url
--> in "Zybex.url"
und machst danacht den Schritt MOVE (auch wieder mit dem MOVE-Befehl).
Das ginge durch eine vorgeschaltete REN-Zeile vor der Zeile mit MOVE:
[/Edit]
Grüße
Biber
Wie teuer is' nochmal dieses Redmonder Standard-Betriebssystem?
sieht in der Tat so aus, als hättest Du den bislang undokumentierten M$-Bug No. #138654 gefunden. Eventuell wird der mal nach Dir benannt.
Also, der MOVE-Befehl scheint offensichtliche Probleme mit diesen langen Dateinamen (oder den vielen Leerzeichen im Namen?)" zu haben.
Einfache Verifizierung dieser rufschädigenden Behauptung am CMD-Prompt:
[einzugebende Zeilen beginnen mit ">"]
>set "var=Zybex - Cheatcodes - Computer Cheat - Cheat Code - Internet Game Cheats - PC Cheat - PC Codes - PC Game Codes -PC Games Cheat.txt"
>echo x>"%var%"
>move "%var%" 00500
Der Dateiname oder die Erweiterung ist zu lang.
Workaround.
Mach den MOVE-Befehl in zwei Schritten,
Zuerst COPY von A nach B, dann Löschen in A.
Konkret:
STREICHE:
MOVE %1 %Akt%
SETZE:
COPY %1 %Akt%
DEL %1
[Edit] Oder aber (Alternative II):DEL %1
Oder Du benennst diese etwas sperrigen Dateinamen um
-> von: "Zybex - {endloses sinnfreies Reklamegelumpe}.url
--> in "Zybex.url"
und machst danacht den Schritt MOVE (auch wieder mit dem MOVE-Befehl).
Das ginge durch eine vorgeschaltete REN-Zeile vor der Zeile mit MOVE:
...
FOR %%i in (%1) do FOR /F %%j in ("%%i") do (
REN %1 %%j%%~xi
MOVE %%j%%~xi %Akt%
)
REM Dieses FOR-Konstrukt STATT der Zeile "MOVE %1 %Akt%"
...
Grüße
Biber
Wie teuer is' nochmal dieses Redmonder Standard-Betriebssystem?