ichotolot2
Goto Top

Unterordner auf Basis eines Teils des Dateinamens erstellen - Dateien da rein verschieben

Hilfsfunktion zum Dateien sortieren

Hallo Leute,

ich habe folgendes Problem:
einen (na gut mehrere) Ordner mit (je) mehr als 10.000 Dateien drin.

Ich möchte eigentlich per Script (oder wenn es das gibt per Programm mit DAU-tauglicher-GUI für kleine Icho's) anhand der Dateinamen Ordner erstellen und die Dateien in diese Ordner verschieben.
Wichtig dabei wäre, dass die Anzahl der zu berücksichtigenden Zeichen festzulegen ist. im Beispiel X
Wünschenswert wäre noch eine Variable für die Anzahl der mindest vorhandenen Dateien (allerdings fürchte ich, das dadurch das Script für mich endgültig zu hoch werden würde) im Beispiel y

ein Beispiel
folgende Dateien:
000.jpg
abcs.jpg
gate1111.avi
gate1112.avi
gate1113.avi
pic000.jpg
pic1.jpg
pic237.jpg
picturegrabb.jpg
einfache Variante:
wenn ich eine Befehl mit der Variablen X=3 absetze sollte die Kiste mir folgende Ordner erstellen:
000abcgatpic
und jeweils die Dateien in den Ordner verschieben.
geniale Variante:
wenn ich eine Befehl mit der Variablen X=3 und y=3 absetze sollte die Kiste mir folgende Ordner erstellen:
gatpic
und jeweils die Dateien gat* und pic* in den Ordner verschieben.

Ich hoffe ich habe meine Wunschtraum einigermaßen verständlich rüber gebracht. Wäre Super wenn ich ein paar Tips für Lösungsansätze bekomme.

System ist übrigens Windows XP.

So jetzt gehe ich mal schlafen
Nice Day

Icho Tolot

Content-Key: 36428

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

Ausgedruckt am: 28.03.2024 um 22:03 Uhr

Mitglied: Biber
Biber 21.07.2006 um 11:00:26 Uhr
Goto Top
Moin Langschläfer, face-wink

kurze Skizze:
::--------Snipp SortintoSubdDirs.bat
@echo off & setlocal EnableDelayedExpansion
If [%1]== %0 *.*
If [%2]== %0 %1 254
Echo %0:...gesetzte Parameter sind Dateifilter: [%1] Länge: [%2]
For /f %%i in ('dir /A:-d /b %1') do (  
       set "tmpv=%%i"  
       echo Datei [%%i] soll in Verzeichnis [!tmpv:~0,%2!]
       If not exist "!tmpv:~0,%2!" ECHO ..existiert nicht... md !tmpv:~0,%2!  
       If     exist "!tmpv:~0,%2!" ECHO ..verschiebe..     move "%%i" !tmpv:~0,%2!\*.*  
)       
::--------Snapp SortintoSubdDirs.bat
goto :eof

Output beim Test (Die ganzen Simulations-Echos müssen natürlich rausgenommen werden... 
>f:\sortintoSubdirs.bat w*.* 4
f:\sortintoSubdirs.bat:...gesetzte Parameter sind Dateifilter: [w*.*] Länge: [4]
Datei [w2rksupp.chm] soll in Verzeichnis [w2rk]
..existiert nicht... md w2rk
..verschiebe..     move "w2rksupp.chm" w2rk\*.*  
Datei [Week.vbs] soll in Verzeichnis [Week]
..existiert nicht... md Week
..verschiebe..     move "Week.vbs" Week\*.*  
Datei [werte.txt] soll in Verzeichnis [wert]
..existiert nicht... md wert
..verschiebe..     move "werte.txt" wert\*.*  
Datei [WindowsXP-KB912919-x86-DEU.exe] soll in Verzeichnis [Wind]
..existiert nicht... md Wind
..verschiebe..     move "WindowsXP-KB912919-x86-DEU.exe" Wind\*.*  
Datei [winguides_com_registryguide2003.exe] soll in Verzeichnis [wing]
..existiert nicht... md wing
..verschiebe..     move "winguides_com_registryguide2003.exe" wing\*.*  

HTH Biber
Mitglied: IchoTolot2
IchoTolot2 21.07.2006 um 12:06:48 Uhr
Goto Top
Hi Biber,

erstmal vielen Dank für die Super schnelle und gute Antwort.
Bin echt erstaunt was mit Batch alles geht, wenn man weiß was man tut.

So habe ich das Teil zum Laufen gebracht
::--------Snipp SortDir.bat
@echo off & setlocal EnableDelayedExpansion
If [%1]== %0 *.*
If [%2]== %0 %1 254
Echo %0:...gesetzte Parameter sind Dateifilter: [%1] Länge: [%2]
For /f %%i in ('dir /A:-d /b %1 %2') do (  
       set "tmpv=%%i"  
       echo Datei [%%i] soll in Verzeichnis [!tmpv:~0,%2!]
       If not exist "!tmpv:~0,%2!" ECHO ..existiert nicht... md !tmpv:~0,%2!  
       If     exist "!tmpv:~0,%2!" ECHO ..verschiebe..        move !tmpv:~0,%2!%1 !tmpv:~0,%2!  
)       
::--------Snapp SortDir.bat
goto :eof
Schmeißt zwar massen an Fehlermeldungen aber es geht.
Deine Variante wollte irgendwie nicht mit Dateien die Leerzeichen enthalten zusammenarbeiten.

Für die geniale Variante werde ich vermutlich nicht an einem WSH-Script o.ä. vorbei kommen.

Liebe Grüße und Nice Day
Icho Tolot
Mitglied: Biber
Biber 21.07.2006 um 12:39:01 Uhr
Goto Top
Moin Icho Tolot,

Schmeißt zwar massen an Fehlermeldungen aber es geht.
Ja und? Erwartete Fehler lassen sich doch abfangen. Egal ob Batch oder WSH oder C#.

Deine Variante wollte irgendwie nicht mit Dateien die Leerzeichen enthalten zusammenarbeiten.
Das halte ich für ein lösbares Problem.
Bei mir bekomme ich das weg ..
>f:\sortintoSubdirs.bat
f:\sortintoSubdirs.bat:...gesetzte Parameter sind Dateifilter: [*langername1.*] Länge: [4]
Datei [test langername1.txt] soll in Verzeichnis [test]
..existiert nicht... md test
..verschiebe..     move "test langername1.txt" test\*.*  

...durch die Änderung der For-Schleifen-Parameter in:
...
For /f "tokens=1* delims=" %%i in ('dir /A:-d /b "%1"') do (
...
Und die Meldung "Datei nicht gefunden" beim DIR-Befehle lässt sich mit "2>nul" entsorgen.

Du wolltest doch nur einen Denkanstoss, kein schlüsselfertiges Produktiv-Programm. face-wink


Für die geniale Variante werde ich vermutlich nicht an einem WSH-Script o.ä. vorbei kommen.
Na, dann lese ich mal gespannt weiter mit.
Mitglied: IchoTolot2
IchoTolot2 22.07.2006 um 01:01:52 Uhr
Goto Top
so, ich habe jetzt mal die einfache Variante einigermaßen als VBScript hin bekommen.

hier das Ergebnis:

'Sortiert Dateien in Unterverzeichnisse  

Set WSHShell = WScript.CreateObject("WScript.Shell")  
Set fso      = WScript.CreateObject("Scripting.FileSystemObject")  
set oArgs    = Wscript.Arguments 

If oArgs.Count > 0 Then                      ' gibt es Argumente?   
  Pfad = oArgs.item(0)                       ' erstes Argument   

  if fso.FileExists( Pfad ) then Pfad = fso.GetParentFolderName( Pfad ) 
     ' obige Zeile wird nur ausgeführt, wenn "Pfad" eine Datei ist  

Else                                         ' es gibt keine Argumente!  
  Pfad = fso.GetFolder( "." )                ' Verzeichnis, in dem sich das Skript befindet  
End If 
 
if not fso.FolderExists( Pfad ) then
  MsgBox UCase(Pfad) & "   existiert nicht!" & vbCRLF & vbCRLF & " . . . das ist das Ende.", , WScript.ScriptName  
  WScript.Quit
End If

'	DFilte = "*.*"	bisher ungenutzt  
	Laenge = 4		'später über InputBox oder Argument  
'	Anzahl = 5		bisher ungenutzt  


' Dateiliste an Array übergeben  
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
i = 0
Set oFolders = fso.GetFolder( Pfad )  
Set oFiles   = oFolders.Files
  For Each DateiX In oFiles
    ReDim Preserve Datei(i)
                   Datei(i) = DateiX.Name 
    i = i + 1
  Next
Set oFiles   = nothing
Set oFolders = nothing

'Verarbeitung  
If i > 0 then                                ' wenn es Datei(en) gibt   
  For i = 0 to UBound( Datei )
	NPfad = Left(Datei(i),Laenge)
	If (fso.FolderExists(NPfad)) Then
		fso.MoveFile Datei(i), Pfad & "\" & NPfad & "\"  
	else
		fso.CreateFolder Pfad & "\" & NPfad  
		fso.MoveFile Datei(i), Pfad & "\" & NPfad & "\"  
	end if
  Next
End If

An der genialen Variante grübel ich derzeit noch ohne große Ideen

Gute Nacht

Icho Tolot
Mitglied: IchoTolot2
IchoTolot2 23.07.2006 um 12:39:21 Uhr
Goto Top
Guten Morgen,

die geniale Variante habe ich jetzt auch zum Laufen gebracht.

Falls es jemand nachbauen will:

back-to-top1. Schritt: Aus dem Dateilistenarray ein Array mit den Pfadnamen generieren

  For i = 0 to UBound( Datei )
	NPfad = Trim(Left(Datei(i),Laenge))
	ReDim Preserve UPfad(i)
	               UPfad(i) = NPfad
  Next

back-to-top2. Schritt: Die Anzahl der gleichen Pfade zählen

  FZaehler = 0
  y = 0
  XPfad = LCase(UPfad(y))
  For i = 0 to UBound( UPfad )
	if LCase(UPfad(i)) = XPfad then
		FZaehler = FZaehler + 1
	else
		ReDim Preserve YPfad(y)	
		               YPfad(y) = XPfad
		ReDim Preserve YZaehl(y)
		               YZaehl(y) = FZaehler
		XPfad = LCase(UPfad(i))
		FZaehler = 1
		y = y + 1
	end if
  Next
'fuers letzte Verzeichnis  
  If FZaehler > 1 then
		ReDim Preserve YPfad(y)	
		               YPfad(y) = XPfad
		ReDim Preserve YZaehl(y)
		               YZaehl(y) = FZaehler
		y = y + 1
  end if

back-to-top3. Schritt: Wenn die Anzahl der Dateien >= der Mindestanzahl sind ein Verzeichnis anlegen

For y = 0 to UBound( YPfad )
	if YZaehl(y) >= Anzahl then
		If (fso.FolderExists(Pfad & "\" & YPfad(y))) = false Then  
			fso.CreateFolder Pfad & "\" & YPfad(y)  
		end if
	end if
Next

back-to-top4. Schritt: Dateien verschieben wenn das zugehörige Unterverzeichnis existiert

For i = 0 to UBound( Datei )
	If (fso.FolderExists(UPfad(i))) Then
		if (fso.FileExists(Pfad & "\" & UPfad(i) & "\" & Datei(i))) = false then  
			fso.MoveFile Pfad & "\" & Datei(i), Pfad & "\" & UPfad(i) & "\"  
		end if
	end if
Next

back-to-topProblem: Keine Dateifilter


Das Einzige wofür ich noch keine Lösung gefunden habe ist eine Möglichkeit der Dateifilterung wie *.avi, p*.jpg oder ähnliches.
Gibt es da Möglichkeiten und wenn ja wie schauen die aus?


Vielen Dank für die Hilfe
Icho Tolot
Mitglied: Biber
Biber 20.08.2006 um 16:17:42 Uhr
Goto Top
Moin Icho Talot,

vielen Dank für das Posten der genialen Varianten.
Hast Du denn das letzte Teilproblem inzwischen auch gefixt?
Oder wartest Du noch auf Antworten?

If so, dann poste doch mal bitte Deinen Code-Schnipsel ein bloc ...ist sonst etwas mühsam, sich das zusammenzustoppeln.
(jedenfalls für ältere Biber wie mich face-wink )

Wenn Frage erledigt sein sollte, dann setze bitte den Beitrag auf gelöst.

Oder, noch eine "geniale Variante" mehr - wir fixen den Rest auch noch und stufen es um als Tutorial.

Gruß
Biber
Mitglied: IchoTolot2
IchoTolot2 28.08.2006 um 17:22:50 Uhr
Goto Top
Hallo Biber und Rest der Welt,
hier erstmal der Code in Block inkl. dem HTML-Logfile:

'Sortiert Dateien in Unterverzeichnisse  
Dim Log 


Set WSHShell = WScript.CreateObject("WScript.Shell")  
Set fso      = WScript.CreateObject("Scripting.FileSystemObject")  
Set oArgs    = Wscript.Arguments 



If oArgs.Count > 0 Then 
  Pfad = oArgs.item(0)                       ' erstes Argument   

  if fso.FileExists( Pfad ) then Pfad = fso.GetParentFolderName( Pfad ) 
     ' obige Zeile wird nur ausgeführt, wenn "Pfad" eine Datei ist  

else 
	Pfad = OrdnerWahl()
end if

if not fso.FolderExists( Pfad ) then
  MsgBox UCase(Pfad) & "   existiert nicht!" & vbCRLF & vbCRLF & " . . . das ist das Ende.", , WScript.ScriptName  
  WScript.Quit
End If

'	DFilte = InputBox("Bitte geben Sie einen Dateifilter an!","Dateifilter","*.*")  
'Bis jetzt keine mit vernünftigem Aufwand realisierbare Variante gefunden  

	Laenge = InputBox("Bitte geben Sie die Anzahl der zu berücksichtigenden Zeichen des Dateinamens an!","Dateifilter",8)  
	If Laenge = "" Then  
	 	WScript.Quit
	ElseIf IsNumeric(Laenge) = False then
		WScript.Quit
	ElseIf Laenge > 256 then
		WScript.Quit
	Else
		Laenge = CByte(Laenge)
	End If
	Anzahl = InputBox("Bitte geben Sie die Mindestanzahl an Dateien an!","Dateifilter",11)  
	If Anzahl = "" Then  
	 	WScript.Quit
	ElseIf IsNumeric(Anzahl) = False then
		WScript.Quit
	ElseIf Anzahl > 256 then
		WScript.Quit
	Else
		Anzahl = CByte(Anzahl)
	End If
	Log    = MsgBox("Logdatei erstellen?", vbYesNo, "Logging")  
 
' Dateiliste an Array übergeben  
' -----------------------------  
i = 0
Set oFolders = fso.GetFolder( Pfad )  
Set oFiles   = oFolders.Files
  For Each DateiX In oFiles
    ReDim Preserve Datei(i)
                   Datei(i) = DateiX.Name 
    i = i + 1
  Next
Set oFiles   = nothing
Set oFolders = nothing
If i = 0 then
  MsgBox "Keine Dateien in " & UCase(Pfad) & vbCRLF & vbCRLF & " . . . das ist das Ende.", , WScript.ScriptName  
  WScript.Quit
End If

'Log HTML starten  
'---------------  
if Log = 6 then
	if month(now)<10 then Monat = "0" & month(now) else Monat = month(now)  
	if day(now)<10 then Tag = "0" & day(now) else Tag = day(now)  
	if hour(now)<10 then Stunde = "0" & hour(now) else Stunde = hour(now)  
	if minute(now)<10 then Minuten = "0" & minute(now) else Minuten = minute(now)  
	Dateiname = "SortDir " & year(now) & "-" & Monat & "-" & Tag & "h" & Stunde & "m" & Minuten  
	LogDatei = HTMLKopf(Pfad, Dateiname, Laenge, Anzahl, i)
end if

'Muster : if Log = 6 then HTMLLog LogDatei, "Ordner", "mag ich nicht sagen", "erstellt"  



'Array mit dem zukünftigen Pfad bilden  
'-------------------------------------  
' hier könnte man noch eine Syntaxkontrolle einbauen  

  For i = 0 to UBound( Datei )
	NPfad = Trim(Left(Datei(i),Laenge))
	ReDim Preserve UPfad(i)
	               UPfad(i) = NPfad
  Next

'Neues Array mit dem Pfad und eines Mit der Anzahl der Dateien bilden  
'--------------------------------------------------------------------  
  FZaehler = 0
  y = 0
  XPfad = UPfad(y)
  For i = 0 to UBound( UPfad )
	if StrComp(UPfad(i), XPfad , 1) = 0 then
		FZaehler = FZaehler + 1
	else
		ReDim Preserve YPfad(y)	
		               YPfad(y) = XPfad
		ReDim Preserve YZaehl(y)
		               YZaehl(y) = FZaehler
		XPfad = UPfad(i)
		FZaehler = 1
		y = y + 1
	end if
  Next
'fuers letzte Verzeichnis  
  If FZaehler > 1 then
		ReDim Preserve YPfad(y)	
		               YPfad(y) = XPfad
		ReDim Preserve YZaehl(y)
		               YZaehl(y) = FZaehler
		y = y + 1
  end if

'Ordner erstellen wenn die Mindestanzahl an Dateien erfüllt ist  
'--------------------------------------------------------------  
For y = 0 to UBound( YPfad )
	if YZaehl(y) >= Anzahl then
		If (fso.FolderExists(Pfad & "\" & YPfad(y))) = false Then  
			fso.CreateFolder Pfad & "\" & YPfad(y)  
			if Log = 6 then HTMLLog LogDatei, "Ordner", YPfad(y), "<font color=green>Verzeichnis erstellt</font>"  
		else
			if Log = 6 then HTMLLog LogDatei, "Ordner", YPfad(y), "<font color=red>nicht erstellt: Verzeichnis bereits vorhanden</font>"  
		end if
	else
'		if Log = 6 then HTMLLog LogDatei, "Ordner", YPfad(y), "nicht erstellt: nur " & YZaehl(y) & " Dateien"  
	end if
Next

'Verschieben der Dateien falls ein Ordner existiert  
'--------------------------------------------------  
'Ich nehme absichtlich das alte Dateilisting, damit eine evtl. Logdatei oder zwischenzeitlich hinzu gekommene Dateien nicht angefasst werden  
'UPfad wird deswegen an Stelle von Len(Datei(i),Laenge) verwendet damit evtl. syntaxkorrekturen berücksichtigt werden  
For i = 0 to UBound( Datei )
	If (fso.FolderExists(Pfad & "\" & UPfad(i))) Then  
		if (fso.FileExists(Pfad & "\" & UPfad(i) & "\" & Datei(i))) = false then  
			fso.MoveFile Pfad & "\" & Datei(i), Pfad & "\" & UPfad(i) & "\"  
			if Log = 6 then HTMLLog LogDatei, "Datei", Datei(i), "<font color=green>verschoben nach: " & UPfad(i) & "</font>"  
		else
			if Log = 6 then HTMLLog LogDatei, "Datei", Datei(i), "<font color=red>bereits im Unterordner <b>" & UPfad(i) & "</b> vorhanden</font>"  
		end if
	else
'		if Log = 6 then HTMLLog LogDatei, "Datei", Datei(i), "nicht verschoben"  
	end if
Next

'Log HTML beenden  
'---------------  
if Log = 6 then
	HTMLFuss LogDatei
end if

Set WSHShell = nothing
Set fso      = nothing
Set oArgs    = nothing

WScript.Quit

function OrdnerWahl()
'Zeigt den Select Folder Dialog an  
	set shell = CreateObject("Shell.Application")  
	AuswahlTitel = "Geben Sie das Verzeichnis an in dem Sortiert werden soll"  
	StartOrdner = 17
	Set retVal = shell.BrowseForFolder(0,AuswahlTitel, &H200,StartOrdner)
	set parent = retVal.ParentFolder
	set Rpath = parent.items
	for each item in Rpath
		if item.Name = retVal.Title then PfadName = item.Path
	next
	OrdnerWahl = PfadName
	set shell = nothing
	set retVal = nothing
	set parent = nothing
	set RPath = nothing
end function

function HTMLKopf(Pfad, Dateiname, Laenge, Anzahl, Dateianzahl)
'erstellt die Logdatei und erfasst die Kopfdaten der HTML-Datei.  
'Gibt die Datei zurück falls Änderungen auftreten sowie für die übrigen HTML-Funktionen  
	Endung = ".htm"  
	sPath = Pfad & "\" & Dateiname & Endung  
	d = 1
	do while fso.FileExists( sPath )
		Dateiname = Dateiname & "-" & d  
		sPath = Pfad & "\" & Dateiname & Endung	  
		d = d + 1
	loop
	Set LogFile = fso.OpenTextFile(sPath, 8, true, -2)
	LogFile.Write("<html>" & vbCrLf & "<head>" & vbCrLf & "<title>LogFile SortDir-Skript</title>" & vbCrLf & "</head>" & vbCrLf & _  
			"<body>" & vbCrLf & "<h3>&Uuml;bergebene Parameter:</h3>" & vbCrLf & "<table bolder=0>" & vbCrLf & _  
			"<tr><td align=right><b>Pfad:&nbsp;</b></td><td>" & Pfad & "</td></tr>" & vbCrLf & _  
			"<tr><td align=right><b>Filter:&nbsp;</b></td><td>" & "*.* (derzeit nicht anders M&ouml;glich)" & "</td></tr>" & vbCrLf & _  
			"<tr><td align=right><b>Zeichen des Dateinamens:&nbsp;</b></td><td>" & Laenge & "</td></tr>" & vbCrLf & _  
			"<tr><td align=right><b>Mindestanzahl der Dateien:&nbsp;</b></td><td>" & Anzahl & "</td></tr>" & vbCrLf & _  
			"<tr><td align=right><b>Anzahl zu pr&uuml;fender Dateien:&nbsp;</b></td><td>" & Dateianzahl & "</td></tr>" & vbCrLf & _  
			"</table>" & vbCrLf & "<p>Folgende &Auml;nderungen wurden vorgenommen:</p>" & vbCrLf & "<table border=1 width=90% align=center>" & vbCrLf & _  
			"<tr><th>Zeit</th><th>Typ</th><th>Name</th><th>Ereignis</th></tr>" & vbCrLf & _  
			"<tr><td align=center>" & now & "</td><td colspan=2 align=center>&nbsp;</td><td>Lauf-Beginn</td></tr>" & vbCrLf)  
	LogFile.close
	set LogFile = nothing
	HTMLKopf = sPath
end function

function HTMLLog(LogDatei, Typ, Name, Ereignis)
'erfasst einen Tabelleneintrag der HTML-Datei.  
	Set LogFile = fso.OpenTextFile(LogDatei, 8, true, -2)
	LogFile.Write("<tr><td align=center>" & now & "</td><td align=center>" & Typ & "</td><td>" & Name & "</td><td>" & Ereignis & "</td></tr>" & vbCrLf)  
	LogFile.close
	set LogFile = nothing
end function

function HTMLFuss(LogDatei)
'erfasst die Fußdaten der HTML-Datei.  
	Set LogFile = fso.OpenTextFile(LogDatei, 8, true, -2)
	LogFile.Write("<tr><td align=center>" & now & "</td><td colspan=2 align=center>&nbsp;</td><td>Lauf-Ende</td></tr>" & vbCrLf & _  
			"</table></body></html>")  
	LogFile.close
	set LogFile = nothing
end function
Das Problem mit dem Dateifilter ist noch nicht gelöst.

Am Code wären noch einige Schönheitsoperationen (ein statt mehrere Arrays u.ä.) notwendig, aber setze ich mich auseinander wenn es mal Komplett läuft.

So genug Text für heute (ich habe ja den ganzen Code abgetippt face-wink ).

Nice Day
IchoTolot
Mitglied: n4426
n4426 10.09.2006 um 17:46:57 Uhr
Goto Top
Hi Biber,

ist es möglich das script von Dir so zu ändern, das es die Länge des Namens des Ordners nicht aus einer festen Zeichenzahl (z.B. 5) sondern aus einem Trennzeichen (z.B. "-" )?

oder geht das mit dem Script nicht so einfach?

mfg
andi
Mitglied: Biber
Biber 11.09.2006 um 00:07:45 Uhr
Goto Top
Moin n4426,

ließe sich natürlich auch machen... wenn es für so etwas Anforderungen gibt?

Angenommen ich hätte meine Datei z.B. jahrweise nach dem Muster 2005-bla.* und 2006-blubb.* benannt, dann könnte ich die in Unterverzeichnisse 2005 und 2006 sortieren wollen.

Skizze:
::--------Snipp SortintoSubDirs2.bat
@echo off & setlocal EnableDelayedExpansion
If [%1]== %0 *.*
Set /a maxlen=8 
Echo %0:...gesetzt Dateifilter: [%1]; Trennzeichen: [%2]
For /f %%i in ('dir /A:-d /b "%1" ^2^>nul') do call :moveIt %%i %2  
goto :eof
~~~~~~~
:moveIt parameter1: Dateiname para2: Trennzeichen
set "tmpv=%1" & set /a pos=0  
For /L %%a in (1,1,%maxlen%) do if !pos!== 0 call :getpos %1 %%a %2
If %Pos%==0 goto :eof
set tmpv=!tmpv:~0,%pos%!
echo Datei [%1] soll in Verzeichnis [%tmpv%]
If not exist "%tmpv%" ECHO ..existiert nicht... md %tmpv% ...move "%1" %tmpv%\*.*  
If     exist "%tmpv%" ECHO ..verschiebe..     move "%1" %tmpv%\*.*  
goto :eof
~~~~~~~
:getpos Para1: textstring; Para2: aktuelle Pos; Para3: gesuchtes Zeichen
 set str=%1
 If "!str:~%2,1!"=="%3" Set Pos=%2  
::--------Snapp SortintoSubDirs2.bat

Test am CMD-Prompt:
$cmd$l:\SortIntoSubDirs2 d:\temp\*-*.* -
l:\SortIntoSubDirs2:...gesetzt Dateifilter: [d:\temp\*-*.*]; Trennzeichen: [-]
Datei [2005-08-17Outlook.rwz] soll in Verzeichnis [2005]
..existiert nicht... md 2005 ...move "2005-08-17Outlook.rwz" 2005\*.*  
Datei [2005-12-11SpywareDoc.htm] soll in Verzeichnis [2005]
..existiert nicht... md 2005 ...move "2005-12-11SpywareDoc.htm" 2005\*.*  

...falls ich Dich richtig verstanden habe.
Sonst musst Du mal ein genaueres Beispiel posten.

Gruß
Biber
[Edit]
P.S. Ich habe das jetzt nicht getestet bzw. angepasst für "Dateinamen mit Leerzeichen.xyz". Würde sicher noch nicht funktionieren.
P.P.S. Und auch die Anweisung For /L %%a in (1,1,%maxlen%) do könnte noch angepasst werden, weil es ja vielleicht nicht sinnvoll ist, ab Zeichen 1 zu suchen nach dem Trennzeichen. Falls ich meine Dateien mit "YYYY-MM-TTdateiname.xyz" sortieren will in Monats-Ordner z.B "2005-07" etc., dann würde ich die Anweisung ändern auf For /L %%a in (5,1,%maxlen%) do... oder die "AbStartPos" auch als Parameter übergeben.
[/Edit]
Mitglied: n4426
n4426 12.09.2006 um 16:06:21 Uhr
Goto Top
Hi Biber,

erstmal Danke, ich habs aber leider nich zum laufen bekommen.

Also, ich möchte folgendes machen.

Ich hab ein Verzeichniss, wo mp3-Datein abgelegt sind. Diese liegen zurzeit alle in einem Ordner.

Interpret - Titel.mp3
Interpret - Titel2.mp3
Interpret2 - Titel3.mp3
Interpret3 - Titel4.mp3
Interpret3 - Titel5.mp3
...

um jetzt schneller die Titel zu finden, möchte ich die Dateien je nach Interpreten in unterverzeichnisse verschieben.

Interpret
.. Interpret - Titel.mp3
.. Interpret - Titel2.mp3
Interpret2
.. Interpret2 - Titel3.mp3
Interpret3
.. Interpret3 - Titel4.mp3
.. Interpret3 - Titel5.mp3

kannst du mir dabei helfen (alle Ordner per Hand erstellen und die Dateinen verschieben ist ja ein ewigkeitswerk).

mfg
andi
Mitglied: Biber
Biber 12.09.2006 um 16:47:17 Uhr
Goto Top
Moin andi,

dafür brauchst Du keinen Batch, das ist nur eine Zeile.
Wenn das so stimmt:
Ich hab ein Verzeichniss, wo mp3-Datein abgelegt sind. Diese liegen zurzeit alle in einem Ordner.

Und wenn alle Dateien vor dem ersten Bindestrich den Interpreten stehen haben.

Beispiel (habe mir ein Spielverzeichnis "F:\mpgs" angelegt)
(=16:35:43  F:\=)
>dir /b f:\mpgs\*.mp3
Interpret5 - Titel2.mp3
Interpret5 - Titel5.mp3
Interpret4 - Titel1.mp3
Interpret1 - Titel22.mp3
Interpret1 - Titel11.mp3

(=16:40:16  F:\=)
>for %i in (f:\mpgs\*-*.mp3) do @for /f "delims=- " %a in ("%~ni") do @echo xcopy /Y "%i" "f:\newRoot\%a\"  
xcopy /Y "f:\mpgs\Interpret5 - Titel2.mp3" "f:\newRoot\Interpret5\"  
xcopy /Y "f:\mpgs\Interpret5 - Titel5.mp3" "f:\newRoot\Interpret5\"  
xcopy /Y "f:\mpgs\Interpret4 - Titel1.mp3" "f:\newRoot\Interpret4\"  
xcopy /Y "f:\mpgs\Interpret1 - Titel22.mp3" "f:\newRoot\Interpret1\"  
xcopy /Y "f:\mpgs\Interpret1 - Titel11.mp3" "f:\newRoot\Interpret1\"  
(=16:40:26  F:\=)

Streiche das @echo vor dem XCopy-Befehl und ändere Quellverzeichnis (="f:\mpgs") und Ziel ("f:\NewRoot") und schieß die Zeile ab.
Und falls Du die Dateien nicht kopieren, sondern de facto verschieben willst, dann häng noch ein [ && del "%i"] dran.
for %i in (f:\mpgs\*-*.mp3) do @for /f "delims=- " %a in ("%~ni") do @(echo xcopy /Y "%i" "f:\newRoot\%a\") && @echo del "%i"  
xcopy /Y "f:\mpgs\Interpret5 - Titel2.mp3" "f:\newRoot\Interpret5\"  
del "f:\mpgs\Interpret5 - Titel2.mp3"  
xcopy /Y "f:\mpgs\Interpret5 - Titel5.mp3" "f:\newRoot\Interpret5\"  
del "f:\mpgs\Interpret5 - Titel5.mp3"  
xcopy /Y "f:\mpgs\Interpret4 - Titel1.mp3" "f:\newRoot\Interpret4\"  
del "f:\mpgs\Interpret4 - Titel1.mp3"  
xcopy /Y "f:\mpgs\Interpret1 - Titel22.mp3" "f:\newRoot\Interpret1\"  
del "f:\mpgs\Interpret1 - Titel22.mp3"  
xcopy /Y "f:\mpgs\Interpret1 - Titel11.mp3" "f:\newRoot\Interpret1\"  
del "f:\mpgs\Interpret1 - Titel11.mp3"  

[Natürlich auch hier beide "@echo"s rauslöschen, wenn es getestet ist.

Gruß
Biber
erstmal Danke, ich habs aber leider nich zum laufen bekommen.
Das liegt sicherlich an der "set maxlen=8" in meinem Batch oben und vor allem an den Leerzeichen in Deinen *.mp3s.
Aber wäre dafür sowieso die falsche Strategie gewesen.
Mitglied: n4426
n4426 12.09.2006 um 19:29:15 Uhr
Goto Top
Danke Biber,

funktioniert prima.

Hat zwar ein bisschen gedauchert, bis ich draufgekommen bin, das man das ganze in Eingebeauforderung eingeben muss und nicht als CMD-Datei laufen lassen kann.
Mitglied: Biber
Biber 12.09.2006 um 20:43:14 Uhr
Goto Top
@n4426
...na, ich hab doch gesagt, dass es nicht nicht lohnt, für eine Zeile einen Batch zu schreiben... face-wink

Aber sicherheitshalber nochmal beiden Varianten:
Zum Testen am CMD-Prompt eintippen:
for %i in (f:\mpgs\*-*.mp3) do @for /f "delims=- " %a in ("%~ni") do @(echo xcopy /Y "%i" "f:\newRoot\%a\") && @echo del "%i"  

wobei f:\mpgs das Verzeichnis mit den Quelldateien ist----------> von denen werden nur die mit den Namen "*-*.mp3" angefasst!
und f:\NewRoot das Verzeichnis ist, unterhalb dem diese neue Struktur mit "InterpretX" aufgebaut werden soll.

Auch wenn ich mich wiederholen sollte: in Deinem konkreten Fall reicht das einmalige Abfeuern vom Prompt aus face-big-smile

Falls jemand meint, es wäre als Batch erhaltenswert, weil man/frau es ja öfters brauchen könnte, dann
als Batch-Version mit zwei Parametern Quellverzeichnis und Zielverzeichnis-Root...
for %%i in (%1\*-*.mp3) do @for /f "delims=- " %%a in ("%%~ni") do @(echo xcopy /Y "%%i" "%2\%%a\") && @echo del "%%i"  

Beide Varianten machen nur ein "echo" von dem, was eigentlich abgehen soll.
Wer es verstanden und "trocken" zum Laufen gebracht hat in der eigenen Umgebung, der muss jeweils das Wort "echo" bzw. "@echo" löschen.

So, nach diesem kurzen Exkurs möchte ich aber noch auf das auch noch offene Problem von Icho Tolot hinweisen... siehe etwas tiefer im Thread.
Kurzgefasst: wie kann ich unaufwändig FileMasks und Patterns in einer VBS-Datei-Auswahl implementieren?
Gab es da nicht auch ein RegExp-Object bei M$? Das riecht doch nach Regular Expressions.. keiner hier, der programmieren kann?

Gruß
Biber
Mitglied: Herby-z
Herby-z 25.09.2006 um 11:53:15 Uhr
Goto Top
Hallo,

ich hoffe Ihr könnt mir weiterhelfen.
Habe mir das alles bereits durchgelesen aber komme trotzdem nicht weiter.

Ich benötige eine bat- bzw. cmd-Datei welche folgendes Problem löst:

Habe einen Ordner Rechnungen mit ca. 25000 Dateien diese sind durchnummeriert (00000-25000).
Einige Nummern sind nicht vorhanden andere mehrfach (z.B. 00009.tif 00009.xls 00009.doc .....)
Einige Ordner wurden auch bereits manuell angelegt und enthalten auch bereits Dateien.

Jetzt soll das Programm den Ordner Rechnungen nach Dateien durchsuchen
und falls Ordner noch nicht vorhanden diesen erstellen und Dateien in Ordner verschieben.
Falls Ordner bereits vorhanden entsprechend nur Dateien verschieben.

Gruss
Herby

Noch ein Nachtrag damit Ihr ungefähr seht wieviel Ahnung ich habe face-smile

Mein bisheriger Versuch:

REM @echo off
set zaehler=0
set stellen=1
:sprungmarke
if "%stellen%"=="1" md C:\Rechnungen\0000%zaehler%
if "%stellen%"=="2" md C:\Rechnungen\000%zaehler%
if "%stellen%"=="3" md C:\Rechnungen\00%zaehler%
set /A zaehler = %zaehler% + 1
if "%zaehler%"=="10" set /A stellen = %stellen%+1
if "%zaehler%"=="100" set /A stellen = %stellen%+1
if not "%zaehler%"=="1000" goto sprungmarke
if "%zaehler%"=="1000" goto ende
:ende

Ziemlich armselig face-sad(((((((((
Mitglied: Biber
Biber 25.09.2006 um 21:03:30 Uhr
Goto Top
Moin, herby_z,

Habe einen Ordner Rechnungen mit ca. 25000 Dateien diese sind durchnummeriert (00000-25000).
Einige Nummern sind nicht vorhanden andere mehrfach (z.B. 00009.tif 00009.xls 00009.doc .....)

Also, wenn ich da einen Vorschlag machen darf.. *kopfschüttel*
Wenn Du diese Dateien schon "strukturiert" verschieben willst (was ich durchaus für angebracht halte),
dann würde ich nicht statt der bisherigen 25000 Dateien in einem Ordner jetzt anstreben, einen Orner mit 20000 Unterverzeichnissen anzulegen.

Wenn schon, dann würde ich;
- alle Rechnungsdateien von 00000 bis 00999 in einen Unterordner 00xxx packen
- darunter dann noch eine Ebene für jeweils 100 Rechnungsnummern
...so dass die Struktur am Ende so aussieht:
[\Rechnungen\]
[\Rechnungen\00xxx]
[\Rechnungen\01xxx]
[\Rechnungen\02xxx]
[\Rechnungen\03xxx]
[\Rechnungen\03xxx\030yy]
[\Rechnungen\03xxx\031yy]
[\Rechnungen\03xxx\032yy] ---> und in so einem Ordner wären alle Dateien 03200.doc bis 03299.tif
[\Rechnungen\25xxx]

Diese Art von stupider Arbeit würde der folgende Zweizeiler gerne für Dich erledigen:
[ACHTUNG: Source-Ordner %src% angenommen als "x:\Archiv" und Zielordner %target% als F:\rechnungen. ANPASSEN!!]
::-snipp MoveIntoRechNo.bat
@echo off & setlocal enableDelayedExpansion & set "target=F:\rechnungen" & set "src=x:\Archiv"  
For /l %%i in (100000,1,125000) do set "fn=%%i" && if exist "%src%\!Fn:~-5!.*" (  
      if not exist "%target%\!Fn:~1,2!xxx\!Fn:~1,3!yy" md %target%\!Fn:~1,2!xxx\!Fn:~1,3!yy  
      move "%src%\!Fn:~-5!.* %target%\!Fn:~1,2!xxx\!Fn:~1,3!yy\ >nul && echo Moved: %target%\!Fn:~1,2!xxx\!Fn:~1,3!yy\!Fn:~-5!.*  
      )      
Output wäre..
  
 (=21:02:16  F:\=)
 >MoveIntoRechno.bat
 Moved: F:\rechnungen\00xxx\000yy\00003.*
 Moved: F:\rechnungen\04xxx\043yy\04333.*
 ....

Wenn Du es lieber in 20000 Einzelverzeichnisse haben willst->auch kein Thema, aber nur auf ausdrücklichen Wunsch und widerwillig.

Gruß
Biber
Mitglied: Herby-z
Herby-z 26.09.2006 um 08:12:00 Uhr
Goto Top
Morgen Biber,

leider brauche ich es in Einzelordner, das hat folgenden Grund:
Diese Rechnungen werden über ein anderes Programm (ERP-System) aufgerufen.

Früher war es nur möglich zu einer Rechnungsnummer eine Datei abzulegen welche im Ordner Rechnungen lag bzw. liegt.

Jetzt kann ich auf Ordner umstellen und in diesen Ordnern mehrere Dateien ablegen welche auch nicht unbedingt die Rechnungsnummer haben müssen.

Ein bischen verwirrend, aber es ist nun mal so.

Auf alle Fälle vielen Dank für die Hilfe werde ich gleich mal testen.

Gruss
Herby
Mitglied: Biber
Biber 26.09.2006 um 08:18:41 Uhr
Goto Top
Na, Herby,
wenn es denn in diese flache Struktur muss, dann wäre es (ungetestet) sinngemäß noch kürzer:
::----snipp MoveIntoRechNo.bat
@echo off & setlocal enableDelayedExpansion & set "target=F:\rechnungen" & set "src=x:\Archiv"  
For /l %%i in (100000,1,125000) do set "fn=%%i" && if exist "%src%\!Fn:~-5!.*" (  
      if not exist "%target%\!Fn:~1,5!" md %target%\!Fn:~1,5!  
      move "%src%\!Fn:~-5!.*" %target%\!Fn:~1,5!\ >nul && echo Moved: %target%\!Fn:~1,5!\!Fn:~-5!.*  
)

Gruß
Biber
Mitglied: Herby-z
Herby-z 26.09.2006 um 09:02:35 Uhr
Goto Top
::----snipp MoveIntoRechNo.bat
@echo off & setlocal enableDelayedExpansion & set "target=C:\rechnungen" & set "src=C:\Archiv"
For /l %%i in (100000,1,125000) do set "fn=%%i" && if exist "%src\!Fn:~-5!.*" (
if not exist "%target%\!Fn:~1,5!" md %target%\!Fn:~1,5!
move "%src%\!Fn:~-5!.* %target%\!Fn:~1,5!\ >nul && echo Gemoved: %target%\!Fn:~1,5!\!Fn:~-5!.*
)


habe das Programme jetzt so abgewandelt das target und source auf C:\ liegen.
Im Ordner C:\rechnungen habe ich eine Datei 13000.txt angelegt.
Leider macht das Programme überhaupt nichts.

Ich verstehe die Batchdatei auch nicht.
Vermute die erste Zeile ist Kommentar, echo off kenn ich auch noch, aber dann siehts ziemlich düster aus.

P.S. Habe WinXP prof. und oben angegebenen Code als Biber.bat gespeichert.
Mitglied: Biber
Biber 26.09.2006 um 09:26:44 Uhr
Goto Top
Im Ordner C:\rechnungen habe ich eine Datei 13000.txt angelegt.
Und wenn Du die mal in den Source-Ordner (da, wo für den Batch die Dateien JETZT liegen sollen) verschiebst?

Wenn Du nachvollziehen willst, was der Batch tut, dann
- ändere die 2. Zeile
ECHO if not exist "%target%\!Fn:~1,5!" md %target%\!Fn:~1,5!
und setze "REM " vor die dritte Zeile.
Dann wird es klarer (denke ich).

Gruß
Biber
Mitglied: Herby-z
Herby-z 26.09.2006 um 09:54:25 Uhr
Goto Top
Könntest Du mir noch die Funktion von !FN:~1,5! und !Fn:~-5! erklären,
ich meine was macht das ! oder ~ ?
Das wandelt doch irgendwie die letzten 5Zeichen um oder so.

Ich glaube das genau hier mein Fehler begraben ist.
Es funktioniert bis do set "Fn=%%i" das wird mir auch angezeigt,
Ordner anlegen und verschieben funktioniert nicht.

Nerv ich schon face-sad((
Mitglied: Biber
Biber 26.09.2006 um 13:27:32 Uhr
Goto Top
Du mir noch die Funktion von !FN:~1,5! und !Fn:~-5! erklären

ja, klar.
in der Variablen %Fn% (für %filename% sollte ja , dur die FOR/L..IN..DO-Anweisung stehen:
100000
100001
100002
125000

Von dieser in der gleichen Zeile gefüllten Variablen will ich sofort/vom aktualisierten Wert, die letzten 5 Zeichen.
Das würde man/frau im Batch eigentlich so schreiben
%fn:~-5% (die letzten 5 Zeichen von %fn% --->die letzten 5 Zeichen von "100000" -->"00000"
%fn:~-5% (die letzten 5 Zeichen von %fn% --->die letzten 5 Zeichen von "100001" -->"00001"
%fn:~-5% (die letzten 5 Zeichen von %fn% --->die letzten 5 Zeichen von "100002" -->"00002"
.. etc.
Da ich aber den Wert der aktualisierten Variablen %fn% brauche, muss ich schreiben:
!fn:~-5! (die letzten 5 Zeichen von der in der selben Zeile geänderten %fn%
-bzw.
!fn:~-1,5! (die Zeichen ab Pos 1 in Länge 5 von der in derselben Zeile geänderten %fn%
[wobei Pos 0 das erste zeichen ist, Pos 1 das zweite Zeichen usw.

Wenn es bei Dir nicht klappt:
->dumme Frage: Du hast aber schon ein halbwegs aktuelles Windows? Win2k, WinXP oder so?
Bei Win98 gibt es die Syntax noch nicht.
-> oder gehörst Du zu den 2% der Windows-User, die aus Versehen "Extensions Enabled" haben?

Dann probier mal zusätzlich (oder als neue 1. Zeile im Bätschelchen)
Setlocal EnableExtensions

Gruß
Biber
Mitglied: Herby-z
Herby-z 26.09.2006 um 13:58:38 Uhr
Goto Top
Hey Biber,

habe den Fehler endlich gefunden !!!!!

::----snipp MoveIntoRechNo.bat
@echo off & setlocal enableDelayedExpansion & set "target=C:\rechnungen" & set "src=C:\Archiv"
For /l %%i in (100000,1,125000) do set "fn=%%i" && if exist "%src\!Fn:~-5!.*" (
if not exist "%target%\!Fn:~1,5!" md %target%\!Fn:~1,5!
move "%src%\!Fn:~-5!.* %target%\!Fn:~1,5!\ >nul && echo Gemoved: %target%\!Fn:~1,5!\!Fn:~-5!.*
)


if exist "%src%\!Fn:~-5!.*" ( hier fehlte zweites %-Zeichen !!!

move "%src%\!Fn:~-5!.* % hier ist das "-Zeichen zu löschen !!!

Aber trotzdem wie mein bei uns in Bayern sagen würde "Host a Maß guat" face-smile
Mitglied: Biber
Biber 26.09.2006 um 14:15:50 Uhr
Goto Top
Na, auf das Maß komm ich auch auch Becks-Trinker gern mal wieder zurück face-wink

Sorry für die Flüchtigkeitsfehler - die Variable %src% habe ich auch tatsächlich erst stehend freihändig hier beim Kommentarschreiben mit drangeflanscht (halt ungetestet).

Na ja, wenn ich so miterlebe, wie lange es braucht, bis wir so einen kleinen Zweizeiler zum Fliegen bringen, dann hab ich auch Verständnis für M$'s Vista-Terminprobleme..

Gruß
Biber
[Edit]
Habe die Tippfehler oben im geposteten Beispiel korrigiert und außerdem noch die Bildschirmmeldung "Echo Gemoved..." in "Echo Moved ..." geändert.

So schlechtes Deutsch wäre mir bestimmt doch irgendwann peinlich..
[/Edit]
Mitglied: Herby-z
Herby-z 27.09.2006 um 09:00:29 Uhr
Goto Top
Guten Morgen Allerseits:

Wie kann ich genau den umgekehrten Effekt erzielen:

::----snipp MoveIntoRechNo.bat
@echo on & setlocal enableDelayedExpansion & set "target=C:\Ziel" & set "src=C:\Start"
For /l %%i in (1000015000,1,1000030000) do set "fn=%%i" && if exist "%src%\!Fn:~-9!.*" (
if not exist "%target%\!Fn:~1,9!" md %target%\!Fn:~1,9!
move /-y %src%\!Fn:~-9!.* %target%\!Fn:~1,9!\ >nul && echo Gemoved: %target%\!Fn:~1,9!\!Fn:~-9!.*
)

Ich möchte gerne eine Batch welche alles wieder in den Urzustand bringt,
d.H. Alle Dateien wieder in einen Ordner und die leeren Ordner löschen.
Nur die leeren Ordner, da ich nur einen bestimmten Bereich zurück moven möchte zwecks Export alter Rechnungen

Gruss
Herby
Mitglied: Herby-z
Herby-z 27.09.2006 um 10:07:13 Uhr
Goto Top
Habe ich tatsächlich selbst geschafft face-smile

::----snipp MoveIntoRechNorueckgaengig.bat

@echo on & setlocal enableDelayedExpansion & set "target=C:\Start" & set "src=C:\Ziel"  

For /l %%i in (1000044000,1,1000045000) do set "fn=%%i" && if exist "%src%\!Fn:~1,9!" (  
     move /-y %src%\!Fn:~1,9!\*.* %target% >nul && rd %src%\!Fn:~1,9!
 )
Mitglied: Biber
Biber 27.09.2006 um 10:45:01 Uhr
Goto Top
Habe ich tatsächlich selbst geschafft
.. war ich auch fest von ausgegangen... face-wink

Das sieht auch so stabil aus, dass Du getrost aus dem "echo on" wieder ein "echo off" machen kannst.

Zumindest Deine Anforderungs-Variante könnten wir jetzt virtuell auf "Gelöst" setzen...

Grüße
Biber
Mitglied: DragonKM
DragonKM 14.11.2006 um 08:04:39 Uhr
Goto Top
öhm ich brauche sowas ähnliches, aber nicht so aufwendig.

Ich hoffe ich bin hier richtig. Es geht sich eigentlich um ein Onlinespiel, für welches man diverse Karten runterladen kann.

Diese Karten sind aufgeteilt in diese Dateitypen:

*.u
*.umx
*.unr
*.uax
*.utx

Diese Dateien sollen aus verschiedenen Ordnern gesucht werden und dann in diese Ordner kopiert werden (nicht verschoben)

unr -> Maps
umx -> Music
uax -> Sounds
u -> System
utx -> Textures

Beispiel:

Auf meiner F-Partition hab ich einen Ordner namens "Maps-Download"
Darin sind ca 2500 Ordner, die alle unterschiedlich benannt sind (z.B. "-=[TMTL]=-SniPeZ")

Das Script soll nun aus diesen Ordnern die betreffenden Dateien suchen, die neuen Ordner anlegen und die Dateien dort rein kopieren.

Soll später so aussehen

F:
-- Maps-Download
Sortiert
Maps
Sounds
Textures
System
Music
Unbekannt


Kann mir da jemand helfen? Ich bin zulange aus den Batch Sachen raus face-sad
Mitglied: Biber
Biber 14.11.2006 um 21:35:20 Uhr
Goto Top
Moin DragonKM,

na ja... Dein Anliegen passt schon unter diese Überschrift...
..aber langsam wird es hier unübersichtlich.
Bitte nächstes Mal einen neuen Thread aufmachen.

Aber lass uns mal zusehen, dass wir Deine Frage diesmal eben noch hier mit abfackeln.

3 Rückfragen vorab:

a) Habe ich das richtig verstanden, dass Du 2500 Ordner mit Namen wie "(z.B.-=[TMTL]=-SniPeZ")
parallel zum vorgesehenen neuen Verzeichnis "Sortiert" unterhalb von "F:\Map-Downloads" haben möchtest?
IMHO wäre es sinnvoller, alles aus den Unterverzeichnissen Krusch, KrimsKrams und Gedöns
unterhalb F:\Map-Downloads herauszukopieren in ein Verzeichnis "F:\Sortiert" eine Ebene höher.

b) Da die Wahrscheinlich relativ hoch ist, das "Kollisionen" auftreten, also eine zu kopierende Datei schon auf eine vorhandene gleichnamige trifft: Was soll passieren?
Letzte gewinnt? Erste bleibt? BSOD aufrufen?

c) How the f*ck spricht man/frau "-=[TMTL]=-SniPeZ" aus???

Wenn Du zumindest die ersten beiden Rückfragen noch beantworten könntest...

Grüße
Biber
Mitglied: DragonKM
DragonKM 15.11.2006 um 05:41:52 Uhr
Goto Top
Ah Biber face-smile Du hast mir schonmal geholfen (erinnerst du Dich?)

Zu 1:

Das ist natürlich auch möglich und sinnvoller

Zu 2:

Die Datei die größer ist soll gewinnen face-smile

Zu 3:

Erklärung

-=[TMTL]=- Ist entweder der Ersteller der Map oder der Clan (Online-Spieler-Gemeinschaft)

SniPeZ = Snaips (Soll wohl sowas wie moderne Sprache sein und lässt auf eine Scharfschützen Map schliessen)


Liebe Grüße

Dragon
Mitglied: Biber
Biber 15.11.2006 um 15:22:57 Uhr
Goto Top
Moin Dragon,

das Schreiben des Schnipsels ist kein Problem...
...nur das Beschreiben dauert.
::--- snipp DragonCopy.bat
@echo off & setlocal
Goto start
~~~~~~~~~~~~~
Eigentlich wieder nur ein Oneliner...
Nur durch diese Bedingung "größere Datei gewinnt" ist dieser Winz-CALL-Block <b>:CopyIfGTR </b> entstanden.  
a) Das Mapping der Extensions auf Ordner wird in den äußeren beiden FOR-Anweisungen abgefackelt.
######## Mapping der Extensions auf Ordner:
unr -> Maps
umx -> Music
uax -> Sounds
u -> System
utx -> Textures
b) das Kopieren läuft in der inneren FOR /R -Anweisung rekursiv unterhalb F:\Maps-Download.
Quellordner (Root) : F:\Maps-Download
Zielordner(root): F:\Sortiert
c) im Moment zeigt der Schnipsel nur, was er tum würde..
Die GROSS geschriebenen ECHO's müssen raus zum Scharfmachen.  

Here we go...

:CopyIfGTR now2Copy alreadyThere
If %~z1 GTR %~z2 <b>ECHO</b> copy /y %1 %2
Goto :eof

:start
Set "QRoot=F:\Maps-Download" && set "ZRoot=F:\Sortiert"  
For %%a in (unr:Maps umx:Music uax:Sounds u:System utx:Textures) do (
  for /f "tokens=1-2 delims=:" %%j in ("%%a") do (  
    for /r "%QRoot%" %%f in (*.%%j) do (  
      If exist "%ZRoot%\%%k\%%~nxf" (  
       Call :CopyIfGtr "%%~ff" "%ZRoot%\%%k\%%~nxf"   
       ) else (
        <b>ECHO</b> copy "%%f" "%Zroot%\%%k\%%~nxf"  
))))
::::--- snapp DragonCopy.bat

Ich habe es versucht, die eventuell zu ändernden Stellen wartbar in Variablen zu halten.
An die krytischen Verarbeitungszeilen musst Du nur zum Entfernen der ECHO's nach dem Testen ran.

Greetz and have fun.
Biber
P.S. Ach ja... bitte gib zügig Rückmeldung... ich möchte diesen Thread hier jetzt endlich schließen.
Mitglied: DragonKM
DragonKM 15.11.2006 um 17:42:39 Uhr
Goto Top
Ok das klappt, ich habe noch folgendes hinzugefügt

:start
if not exist "F:\Sortiert" md F:\Sortiert
if not exist "F:\Sortiert\Maps" md F:\Sortiert\Maps
if not exist "F:\Sortiert\Music" md F:\Sortiert\Music
if not exist "F:\Sortiert\Sounds" md F:\Sortiert\Sounds
if not exist "F:\Sortiert\System" md F:\Sortiert\System
if not exist "F:\Sortiert\Textures" md F:\Sortiert\Textures


Aber was ist mit den Dateien, die nicht in das Suchraster passen? zum Beispiel txt Dateien oder so? Die sollten ja dann direkt in den Sortiert Ordner....
Mitglied: Biber
Biber 15.11.2006 um 18:11:06 Uhr
Goto Top
Moin DragonKM,

na ja, das wird uns nicht so vor massive Probleme stellen, denke ich...
::--- snipp DragonCopy.bat
@echo off & setlocal
Goto start
~~~~~~~~~~~~~
Version 0.02: 
++ Verzeichnisse überprüfen; ggf. anlegen
++ Dateien mit "anderer Endung" als *.u;*.uax.... in den Ordner "%ZRoot%"=F:\Sortiert:  

Eigentlich wieder nur ein Oneliner...
Nur durch diese Bedingung "größere Datei gewinnt" ist dieser Winz-CALL-Block :CopyIfGTR  entstanden.  
a) Das Mapping der Extensions auf Ordner wird in den äußeren beiden FOR-Anweisungen abgefackelt.
######## Mapping der Extensions auf Ordner:
unr -> Maps
umx -> Music
uax -> Sounds
u -> System
utx -> Textures
b) das Kopieren läuft in der inneren FOR /R -Anweisung rekursiv unterhalb F:\Maps-Download.
Quellordner (Root) : F:\Maps-Download
Zielordner(root): F:\Sortiert
c) im Moment zeigt der Schnipsel nur, was er tum würde..
Die GROSS geschriebenen ECHO's müssen raus zum Scharfmachen.  

Here we go...

:CopyIfGTR now2Copy alreadyThere
If %~z1 GTR %~z2 ECHO copy /y %1 %2
Goto :eof

:start
Set "QRoot=F:\Maps-Download" && set "ZRoot=F:\Sortiert"  
For %%a in (unr:Maps umx:Music uax:Sounds u:System utx:Textures ) do (
  for /f "tokens=1-2 delims=:" %%j in ("%%a") do (  
    for /r "%QRoot%" %%f in (*.%%j) do (  
      <b>If not exist  "%ZRoot%\%%k" md "%ZRoot%\%%k"</b>  
      If exist "%ZRoot%\%%k\%%~nxf" (  
       Call :CopyIfGtr "%%~ff" "%ZRoot%\%%k\%%~nxf"   
       ) else (
        ECHO copy "%%f" "%Zroot%\%%k\%%~nxf"  
))))
Rem für den Rest abgespeckte FOR /R -Anweisung:[mit "größere gewinnt"]  
    for /r "%QRoot%" %%f in (*.*) do (  
      If exist "%ZRoot%\%%~nxf" (  
       Call :CopyIfGtr "%%~ff" "%ZRoot%\%%~nxf"   
       ) else (
        ECHO copy "%%f" "%Zroot%\%%~nxf"  
))

Darf ich den Beitrag jetzt schließen? *gg

Grüße
Biber
[Edit]
Eigentlich, da die Dateien ja kopiert werden und nicht verschoben, werden mit dem obigen Schnipsel
auch wieder die Dateien mit den Endungen "*.unr *.umx *.uax *.u *.utx" ein zweites Mal kopiert... in den Ziel-Root-Ordner "F:\Sortiert"
Wenn das nicht sein soll, dann noch mal die untere FOR /R -Anweisung ergänzen:
...
    for /r "%QRoot%" %%f in (*.*) do (  
     <b> If Not [%%xf]==[.unr] If Not [%%xf]==[.umx] If Not [%%xf]==[.uax] If Not [%%xf]==[.u] If Not [%%xf]==[.utx] ( </b> 
      If exist "%ZRoot%\%%~nxf" (  
       Call :CopyIfGtr "%%~ff" "%ZRoot%\%%~nxf"   
       ) else (
        ECHO copy "%%f" "%Zroot%\%%~nxf"  
)) )
REM Unten eine weitere Klammer-Zu nicht vergessen!
[/Edit]
Mitglied: DragonKM
DragonKM 15.11.2006 um 20:52:57 Uhr
Goto Top
Ja kannst dicht machen, geht einwandfrei face-smile Vielen Dank