computerwuffi
Goto Top

Batch zum Verschieben numerisch benannter Dateien möglich?

Geht das?

Hallo,

ich habe auf einem W2K Server tausende Dateien im gleich aufgebauten numerischen Format liegen, Beispiele:

100_1.txt
100_2.jpg
300_4.jpg
1000_1.jpg
140357_1.txt

Da es nun lange Zeit dauert, das Verzeichnis aufzulisten, möchte ich diese Dateien in Order mit 5000er -abstand einsortieren, also:

einen Ordner für alle Dateien 1_* bis 4999_*
einen Ornder für alle dateien 5000_* bis 9999_*
einen Ordner für alle Dateien 10000_* bis 14999_* usw ...

geht das mit einer Batch-Datei? Dabei ist leider nur ein Verschieben der Dateien möglich, weil sonst der Speicherplatz nicht reicht.

ich bin für jede Hilfe dankbar!

Content-ID: 205601

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

Ausgedruckt am: 20.11.2024 um 15:11 Uhr

Pjordorf
Pjordorf 24.04.2013 um 20:33:23 Uhr
Goto Top
Hallo,

Zitat von @computerwuffi:
W2K Server tausende Dateien im gleich aufgebauten numerischen Format
Nein, laut deinem beispiel eben nicht im gleichen Aufbau.

100_1.txt
100_2.jpg
300_4.jpg

Und diese sind eben anders aufgebaut
1000_1.jpg

Und diese wiederum anders aufgebaut
140357_1.txt

face-smile

geht das mit einer Batch-Datei?
Ja das geht.

Gruß,
Peter
bastla
bastla 24.04.2013 aktualisiert um 20:44:38 Uhr
Goto Top
@ Pjordorf
Die Beispiele weisen mE durchaus auf eine Gemeinsamkeit hin, daher könnte ein Batch schematisch etwa so aussehen:
@echo off & setlocal
for %%i in ("D:\Ordner mit vielen Dateien\*_*.*") do (  
    for /f "delims=_" %%z in ("%%~ni") do (  
        set /a Ordner=%%z / 5000 * 5000
        setlocal enabledelayedexpansion
        echo md "D:\Ordner mit vielen Dateien\!Ordner!" 2>nul  
        echo move "%%i" "D:\Ordner mit vielen Dateien\!Ordner!"  
        endlocal
    )
)
pause
Solange die beiden "echo" in den Zeilen 6 und 7 stehen, werden beim Testen (eines Ordners mit vielleicht nur mal 50 entsprechenden Dateien face-wink) jeweils die Befehle zum Erstellen der Unterordners und zum Verschieben nur angezeigt ...

Grüße
bastla
computerwuffi
computerwuffi 24.04.2013 um 21:08:15 Uhr
Goto Top
Hallo Peter,

vielen Dank für deine Antwort. Entschuldige, wenn ich mich etwas unklar ausgedrückt habe. Mit gleich aufgebaut meinte ich im vorderen Teil (vor dem "_" eine Zahl von 1 bis derzeit ca 147000, dann der "_" mit nachfolgender Zahl zwischen 1 und 12, anschliessend eine beliebige Dateiendung.
Meine Denkblockade dabei liegt auch genau bei deinem Aufbauargument, ich weiss nicht, wie ich die einer, zehner, hunderter, tausender, Zehntausender in dem Batch filtern kann.
Wenn ich ein Programm schreiben müsste, würde ich in string umwandeln und dann mit length die Gruppen raussuchen, ab den Aufwand will ich mir möglichst ersparen wenn es anders geht. Da ich nicht viel Erfahrung mit Batch-Dateien habe, habe ich die Anfrage an die Spezialisten gestellt. Ich versuche jetzt mal, das Beispiel von bastla zu testen, auch wenn ich zunächst keine Ahnung habe, was da gemacht wird.

Gruß
Wolfgang
bastla
bastla 24.04.2013 aktualisiert um 21:25:29 Uhr
Goto Top
Hallo computerwuffi und willkommen im Forum!
... auch wenn ich zunächst keine Ahnung habe, was da gemacht wird.
In der Kurzfassung:
  • Entnehme für jede Datei dem Dateinamen den Teil vor dem ersten "_",
  • dividiere diesen Teil ganzzahlig durch 5000 und multipliziere das Ergebnis mit 5000 (das ergibt für 100 den Ordnernamen 0 und für 140357 den Ordnernamen 140000),
  • erstelle den entsprechenden Ordner (und unterdrücke die Fehlermeldung, wenn es den Ordner bereits gibt) und
  • verschiebe die Datei in den errechneten Ordner.

Grüße
bastla
computerwuffi
computerwuffi 24.04.2013 um 21:36:16 Uhr
Goto Top
Hallo bastla,

ganz vielen herzlichen Dank für deine ausführliche Erklärung für einen Newbie, das bringt mich ein riesiges Stück weiter. Morgen werde ich das ganze mal testen.
Das Forum habe ich schon zu meiner Favoriten-Liste hinzugefügt, es ist echt interessant und sehr gut moderiert.

Viele Grüße
computerwuffi
Pjordorf
Pjordorf 24.04.2013 um 22:02:14 Uhr
Goto Top
Hi bastler,

Zitat von @bastla:
Die Beispiele weisen mE durchaus auf eine Gemeinsamkeit hin,
Klar tun sie das. Die haben schon gweisse Gemeinsamkeiten. Wenn er jetzt aber nicht Numerisch sondern textmäßig sortiert uns die Liste präsentiert hätte sähe die schon anders aus. Und manchmal ist es gut einen newbie daran zu errinern das ein Computel eben ganz genau unterscheidet. Und da ein "_" eben keine gültige Zahl darstellt kann ein Computerl eben nur das ganze als text interpretieren udn dann ist eine Sorrtierung eben anders. Hier hat ein mensch die Texte als Nummer interpretiert und diese dann Numerisch aufsteigend sortiert. (Ich weiß, Erbsenzählerei face-smile)

Gruß,
Peter

PS. Wollte nur nicht als Antwort zu seiner Frage eben nur ein "Ja" dort reinschreiben face-smile
Biber
Biber 25.04.2013 um 00:02:36 Uhr
Goto Top
[OT]
Zitat von @computerwuffi:
Das Forum habe ich schon zu meiner Favoriten-Liste hinzugefügt, es ist echt interessant und sehr gut moderiert.
...dabei ist die Moderation in diesem Forum und speziell in diesem Bereich sehr dezent. face-wink

Willkommen im Forum.

Biber
[/OT]
joemouth
joemouth 25.04.2013 um 07:09:45 Uhr
Goto Top
Ich würde es mit zwei FOR /L Schleifen sowie SET /A machen:

FOR /L %Variable IN (Start,Schritt,Ende) DO Befehl [Parameter]

Der Satz ist eine Folge von Zahlen von Start bis Ende und der
angegebenen Schrittweite. So erstellt (1,1,5) die Folge 1 2 3 4 5 und
(5,-1,1) erstellt die Folge (5 4 3 2 1).

Die erste arbeitet in 5000er Schritten, die zweite innere FOR-Schleife in 1er Schritten von 1....4999.

Mit set /A .... kannst Du dann aus den beiden Variablen Deine Dateinamen aufbauen

SET /A Ausdruck

Die /A-Option gibt an, dass die Zeichenfolge rechts vom Gleichheitszeichen
ein numerischer Ausdruck ist, der ausgewertet wird.

Hilft Dir das weiter?
Noobstar0815
Noobstar0815 25.04.2013 um 08:02:54 Uhr
Goto Top
Wenn ich da jetzt an den Kommentar von Pfordorf denke, weiß ich nicht, ob es wirklich ein numerischer Ausdruck ist, da "_" halt wirklich keine Zahl bzw kein numerischer Ausdruck ist :/
Biber
Biber 25.04.2013 aktualisiert um 08:21:53 Uhr
Goto Top
Moin @Noobstar0815,

zum Thema Rausfieseln der numerischen Anteile aus dem Dateinamen hat doch @bastla oben schon alles geschrieben.
...
for %%i in ("D:\Ordner mit vielen Dateien\*_*.*") do ( 
    for /f "delims=_" %%z in ("%%~ni") do ( 
      .....

Mit dem Ansatz von @joemouth liesse sich natürlich das (einmalige) Anlegen der Unterverzeichnisse vorab vom CMD-Prompt aus abfackeln.
Damit könnte im @bastla-schnipsel die md-Zeile entfallen.

C:\Users\Biber>for /L %i in (0, 5000, 70000) do @echo md x:\subdir\%i
md x:\subdir\0
md x:\subdir\5000
md x:\subdir\10000
md x:\subdir\15000
md x:\subdir\20000
md x:\subdir\25000
md x:\subdir\30000
md x:\subdir\35000
md x:\subdir\40000
md x:\subdir\45000
md x:\subdir\50000
md x:\subdir\55000
md x:\subdir\60000
md x:\subdir\65000
md x:\subdir\70000
hier nur mit "@echo" zur Demo; das muss zum Scharfschalten natürlich raus.

(Wobei dann natürlich der Batch auf die Schnauze fällt, wenn ein Verzeichnisname außerhalb des vorab angelegten Nummernkreises angesprochen wird.
Fällt aber in die Rubrik works as designed.)


Grüße
Biber
Endoro
Endoro 25.04.2013 um 08:31:57 Uhr
Goto Top
Hallo Noobstar0815,

Es geht ja nicht darum, 5000 Files in Folder zu verschieben.

Für die "for /l" Lösung würde noch eine weitere Forschleife benötigt, um die höchste Nr. zu ermitteln. Sonst läuft die ja ewig (oder man verlässt sich drauf, dass die Nrn. lückenlos sind).

Gruss!
Noobstar0815
Noobstar0815 25.04.2013 aktualisiert um 08:57:04 Uhr
Goto Top
Könnte man es nicht auch n bissl aufwändiger mit if-Abfragen machen? So nach dem Motto wenn der erste teil des namens kleiner als 5000, 10000, 15000... ist verschiebe sie nach da und da? Oder benötigt man dafür die for-Schleife um den ersten Teil des Namens zu bekommen?
joemouth
joemouth 25.04.2013 um 09:26:07 Uhr
Goto Top
Hallo @all,

ich würde es so machen:

@echo off
setlocal ENABLEEXTENSIONS
setlocal ENABLEDELAYEDEXPANSION

cls

set max1=20000
set s1=5000

set max2=4999
set s2=1

:: Zum Testen
set max1=200
set s1=50

set max2=49
set s2=1

FOR /L %%M IN (0,%s1%,%max1%) DO (
    FOR /L %%N IN (0,%s2%,%max2%) DO (
        set /A z=%%M + %%N
        echo move !z!_*.* %%M
        )
    )

Dann noch mkdir und if exist etc. einbauen

Was meint Ihr?
Endoro
Endoro 25.04.2013 aktualisiert um 10:41:46 Uhr
Goto Top
Zitat von @joemouth:

Was meint Ihr?

KA, müsste man mal testen, was am schnellsten ist. Meine 50 ct:
@echo off&setlocal enabledelayedexpansion
set /a pif=5000 &rem pattern in folder
for %%i in ("test\*_*") do (  
	set "name=%%~ni"  
	set /a folder=(!name:~0,-2!/pif*pif+pif^)
	if not exist "test\!folder!" md "test\!folder!"  
	move "%%~fi" "test\!folder!"  
)

Gruss!


€dit: noch ein Typo korrigiert:
set /a folder=(!name:~0,-1!/pif*pif+pif^) <-- falsch
joemouth
joemouth 25.04.2013 um 09:53:55 Uhr
Goto Top
Zitat von @Endoro:
> ...
> set /a folder=(!name:~0,-1!/pif*pif+pif^)
> ...

Klasse Idee, besser als meine Lösung, die geht "über die Dörfer"
bastla
bastla 25.04.2013 aktualisiert um 10:41:11 Uhr
Goto Top
Hallo Pjordorf!
Und da ein "_" eben keine gültige Zahl darstellt
... verwende ich es als Trennzeichen - davor steht in allen Beispieldateien eine gültige Zahl.
Hier hat ein mensch die Texte als Nummer interpretiert und diese dann Numerisch aufsteigend sortiert.
Das ja - ist aber irrelevant, da ja die Ordnernamen aus der Zahl berechnet werden ...

Grüße
bastla
computerwuffi
computerwuffi 25.04.2013 um 20:36:33 Uhr
Goto Top
Vielen Dank an alle die bei dieser regen Diskussion mit dabei waren. Ich habe heute, nachdem ich vorsichtshalber noch ein Backup gemacht habe, das Script von Endoro laufen lassen. Dort habe ich lediglich Zeile 5 abgeändert in: set /a folder=(!name:~0,-2!/pif*pif^), da ich ja mit Ordner 0 anfangen wollte.

Das Script habe ich vom übergeordneten Verzeichnis mit voll qualifizierten Pfaden gestartet,es lief perfekt durch. (ca 20. Minuten) Danach waren 859.437 Dateien in die richtigen Ordner einsortiert. (so viele, weil nach dem "_" noch bis zu 12 Untergruppen möglich sind)

Nochmal vielen Dank für die tolle Hilfe face-smile