jaglag
Goto Top

Eine Batch zum Sortieren verschiedener Dateien in Ordner

Hallo,

da ich leider mit Batch und shell nicht so erfahren bin hoffe das ein findiger User hier weiterhelfen möchte.
Ich bräuchte für meine Arbeit eine Simple Batch Datei um mehrere Dateien anhand einer Nummer dem entsprechenden Ordner zuzuteilen.
Hier mal der Aufbau:

Ausgangs Ordner -> C:\Users\fahrer\Dropbox\Lieferscheine\
Zielordner -> C:\Users\fahrer\Dropbox\1-7

Datei Template -> Max Mustermann Wohnort - 3 - Lieferschein 2017-32533
die 3 in der Mitte ist die Nummer in diesem Beispiel anhand derer verschoben werden soll.

Die 1-7 steht hierbei für die vorhandenen Zahlen/ordner also 1 bis 7 aber es kommt immer jeweils nur eine nummer zur verwendung.
Die entsprechende Ordner Struktur besteht bereits somit müssten hier nicht notwendigerweise jedesmal überprüft werden ob diese vorhanden sind oder nicht.

eine kleine erklärung der einzelnen Befehle wäre klasse damit ich das nachvollziehen kann und ggf. umändern wenn etwas nichtmehr passen sollte.

Grüße

Jaglag

Content-Key: 344958

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

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

Member: rubberman
rubberman Jul 31, 2017 at 15:48:39 (UTC)
Goto Top
Viel zu ungenau spezifiziert!
Du kannst so etwas nur mit exakt definierten Regeln umsetzen. Dazu muss aber klar sein, was es so alles an Möglichkeiten und Sonderfällen gibt. Beispielsweise könnte man an den Bindestrichen splitten und den zweiten Teilstring annehmen. Geht aber in die Hose, wenn es auch Namen wie Klaus-Dieter Meier-Hofer geben könnte. Falls zum Wohnort auch eine Postleitzahl gehört, könnte man diese als Stringtrenner verwenden. Wenn der Teilstring von "Lieferschein" bis Dateiendung immer eine fixe Länge hat, kann man auch dort ansetzen. Das geht aber alles nicht aus deinem Trivialbeispiel hervor ...

Grüße
rubberman
Member: Jaglag
Jaglag Jul 31, 2017 at 16:06:31 (UTC)
Goto Top
Hallo Rubberman,

ja mein gedanke war das man anhand der Bindestriche trennen könnte da diese immer fix sind inclusive der leerzeichen dazwischen, was bei deinem Beispiel Meier-Hofer nicht gegeben wäre da dies immer zusammen geschrieben wird.
auch hinten könnte man ansetzen da bis wir in einen 6 Stelligen bereich der Lieferscheine kommen noch eine weile vergehen wird.
Member: rubberman
rubberman Jul 31, 2017 updated at 16:46:35 (UTC)
Goto Top
Hmm ... probieren wir es anders.

Lass den Code mal in dem entsprechenden Verzeichnis rennen. Er gibt nur die Nummer und den Dateiname aus. Bitte genau prüfn, ob in jedem Fall die richtige Nummer gefunden wird.
@echo off &setlocal
for /f "delims=" %%i in ('dir /a-d /b^|findstr /rc:"- [1-7] -"') do (  
  set "fname=%%~i"  
  setlocal EnableDelayedExpansion
  call :findnum !fname!
  echo !num! "!fname!"  
  endlocal
)
pause
exit /b

:findnum
set "num="  
if "%1"=="" exit /b  
2>nul set /a "num=%1"  
if not defined num (shift&goto findnum)
if %num% gtr 0 if %num% lss 8 exit /b
shift
goto findnum
Falls das funktioniert, lässt sich das Verschieben der Dateien schnell implementieren.

Grüße
rubberman
Member: Jaglag
Jaglag Jul 31, 2017 at 16:54:54 (UTC)
Goto Top
Danke dir Rubberman,

kann das erst morgen im Geschäft laufen lassen, werde berichten.


Grüße

Jaglag
Member: rubberman
Solution rubberman Jul 31, 2017 updated at 17:57:58 (UTC)
Goto Top
OK, dann schon mal den evtl. realen Code. Renn den aber erst, wenn der erste die richtigen Ergebnisse ausspuckt.

@echo off &setlocal
set "src=C:\Users\fahrer\Dropbox\Lieferscheine\"  
set "dst=C:\Users\fahrer\Dropbox\"  

for /l %%i in (1 1 7) do 2>nul "%dst%%%i"  
for /f "delims=" %%i in ('dir /a-d /b "%src%"^|findstr /rc:"- [1-7] -"') do (  
  set "fname=%%~i"  
  setlocal EnableDelayedExpansion
  call :findnum !fname!
  move "!src!!fname!" "!dst!!num!\"  
  endlocal
)
pause
exit /b

:findnum
set "num="  
if "%1"=="" exit /b  
2>nul set /a "num=%1"  
if not defined num (shift&goto findnum)
if %num% gtr 0 if %num% lss 8 exit /b
shift
goto findnum

Sollte hier noch jemand von den PowerShellern mit einer vernünftigen Regex Lösung vorbei schneien, dann wäre diese zu bevorzugen. Ich verkneife mir für Batch 3rd Party Tools vorzuschlagen, für Dinge bei denen es in der PowerShell Built-In Lösungen gibt.

Grüße
rubberman
Member: Jaglag
Jaglag Aug 01, 2017 updated at 05:58:42 (UTC)
Goto Top
Hallo Rubberman,

Passiert leider nichts bei deinem Lösungsvorschlag, es öffnet sich ein cmd Fenster mit drücken sie eine beliebige Taste und fertig.
Ich weiß leider nicht wie man da an das Log kommt um zu sehen wie und wo das problem liegt.

Edit:
Gerade das problem gefunden es wurden die Lieferscheine verändert.
Die passenden Nummern stehen nun immer am Anfang der Datei als beispiel.
08 - Manfred Mustermann - Lieferschein 2017-33333

Grüße

Jaglag
Member: Jaglag
Jaglag Aug 01, 2017 updated at 06:14:55 (UTC)
Goto Top
Hab das Script etwas angepasst und deinen String verändert nun hat er alle Dateien mit 07 verschoben nur die anderen nicht:

/RC:"[01-07] - "') so habe ich das abgeändert in Zeile 6
Mitglied: 133883
133883 Aug 01, 2017 updated at 08:00:34 (UTC)
Goto Top
Powershell
gci 'C:\Users\fahrer\Dropbox\Lieferscheine' -File | group {[regex]::Match($_.Basename,'^(\d+)').Groups[1].Value} | %{  
    $t = "C:\Users\fahrer\Dropbox\$($_.Name)"  
    if(!(Test-Path $t)){md $t | out-null}
    $_.Group | move-item -destination $t -Force
}
Gruß
Mitglied: 133883
133883 Aug 01, 2017 updated at 08:03:13 (UTC)
Goto Top
Zitat von @Jaglag:
/RC:"[01-07] - "') so habe ich das abgeändert in Zeile 6
Kann ja nicht funktionieren, der Regex geht so nicht .
/RC:"^0[1-7] -"  
Member: Jaglag
Jaglag Aug 01, 2017 updated at 08:48:07 (UTC)
Goto Top
Ich hatte das jetzt so gelöst dass ich [01,02,03 usw. Einzeln aufgelistet habe dies hat funktioniert sieht halt nicht so elegant aus wie bei dir.

Könntest du mir bitte erklären wie ich dieses Shell Script nutze, bei batch ist das ja relativ simpel txt Datei und am ende .bat

Eine weitere Frage falls Mal eine neue Tour bei uns dazu kommen würde also 08 09 usw.
Ich habe testweise gerade mehrere 08 Dateien angelegt diese werden jedoch anstelle von dem entsprechenden Ordner /Dropbox/8 einfach auf /Dropbox abgelegt.

Grüße jaglag
Mitglied: 133883
Solution 133883 Aug 01, 2017 updated at 09:08:29 (UTC)
Goto Top
Mit> Zitat von @Jaglag:

Ich hatte das jetzt so gelöst dass ich [01,02,03 usw. Einzeln aufgelistet habe dies hat funktioniert sieht halt nicht so elegant aus wie bei dir.

Könntest du mir bitte erklären wie ich dieses Shell Script nutze, bei batch ist das ja relativ simpel txt Datei und am ende .bat
Steht überall,das wiederhole ich jetzt nicht nochmals
https://www.windowspro.de/andreas-kroschel/powershell-scripts-ausfuehren
Eine weitere Frage falls Mal eine neue Tour bei uns dazu kommen würde also 08 09 usw.
Ich habe testweise gerade mehrere 08 Dateien angelegt diese werden jedoch anstelle von dem entsprechenden Ordner /Dropbox/8 einfach auf /Dropbox abgelegt.
Bei meinem Powershell Skript bereits berücksichtigt.
Beim Batch einfach den Regex passend erweitern und in der findnum Prozedur die Zahl anpassen, sieht doch ein Blinder mit Krückstock.
Member: rubberman
rubberman Aug 01, 2017 at 12:38:09 (UTC)
Goto Top
Zitat von @Jaglag:
Die passenden Nummern stehen nun immer am Anfang der Datei als beispiel.
08 - Manfred Mustermann - Lieferschein 2017-33333

Ich würde ja die Batchlösung noch etwas vereinfachen wollen (denn die Nummer immer am Anfang zu haben ist viel simpler und benötigt nur noch Regex für den Dateifilter). Dein Beispiel macht es aber wieder etwas komplizierter. 08 ? War nicht bei 07 Schluss? Das ist insofern interessant, als dass die vorangestellte 0 die Zahl in Batch als oktal markiert. Bis 07 ist das egal, aber ein 08 gibt es nicht als oktale Zahl.

Grüße
rubberman
Member: Jaglag
Jaglag Aug 01, 2017 updated at 15:15:55 (UTC)
Goto Top
@echo off &setlocal
for /f "delims=" %%i in ('dir /a-d /b^|findstr /rc:" [01,02,03,04,05,06,07,08] -"') do (  
  set "fname=%%~i"  
  setlocal EnableDelayedExpansion
  call :findnum !fname!
  echo !num! "!fname!"  
  endlocal
)
pause
exit /b

:findnum
set "num="  
if "%1"=="" exit /b  
2>nul set /a "num=%1"  
if not defined num (shift&goto findnum)
if %num% gtr 0 if %num% lss 9 exit /b
shift
goto findnum

Dies war der Code den ich heute hab laufen lassen klappt alles perfekt bis halt auf die nummer 8.
Ja Rubberman das ist richtig aktuell gibt es die 8 nicht bzw. nicht für die Fahrer aber es könnte sein das 8 und 9 noch dazu kommt und ich würde ungern ein altes Thema wieder aufgreifen sondern das script soweit verstehen das ich es bei Bedarf umstellen kann.

@exguru

Bei meinem Powershell Skript bereits berücksichtigt.
Beim Batch einfach den Regex passend erweitern und in der findnum Prozedur die Zahl anpassen, sieht doch ein Blinder mit Krückstock.

ja Regex hatte ich angepasst wie du oben am Script erkennen kannst und bei der findnum Prozedur von 8 auf 9 geändert aber leider hat er es Trotzdem wie vorher beschrieben nicht richtig verschoben.
Member: rubberman
Solution rubberman Aug 01, 2017 updated at 17:03:19 (UTC)
Goto Top
@echo off &setlocal
set "src=C:\Users\fahrer\Dropbox\Lieferscheine\"  
set "dst=C:\Users\fahrer\Dropbox\"  

for /f "delims=" %%i in ('dir /a-d /b "%src%"^|findstr /rbc:"[0-9][0-9] -"') do (  
  set "fname=%%~i"  
  setlocal EnableDelayedExpansion
  set /a "num=1!fname:~,2! %% 100"  
  2>nul md "!dst!!num!"  
  move "!src!!fname!" "!dst!!num!\"  
  endlocal
)
Das C:\Users\fahrer kannst du ggf. durch %userprofile% ersetzen, wenn es sich um das Profil des derzeit angemeldeten Benutzer handelt.

Grüße
rubberman
Member: Jaglag
Jaglag Aug 01, 2017 at 17:00:46 (UTC)
Goto Top
werd ich morgen mal testen Danke!


Grüße

Jaglag
Member: Jaglag
Jaglag Aug 02, 2017 at 16:48:34 (UTC)
Goto Top
Zitat von @rubberman:

@echo off &setlocal
> set "src=C:\Users\fahrer\Dropbox\Lieferscheine\"  
> set "dst=C:\Users\fahrer\Dropbox\"  
> 
> for /f "delims=" %%i in ('dir /a-d /b "%src%"^|findstr /rbc:"[0-9][0-9] -"') do (  
>   set "fname=%%~i"  
>   setlocal EnableDelayedExpansion
>   set /a "num=1!fname:~,2! %% 100"  
>   2>nul md "!dst!!num!"  
>   move "!src!!fname!" "!dst!!num!\"  
>   endlocal
> )
Das C:\Users\fahrer kannst du ggf. durch %userprofile% ersetzen, wenn es sich um das Profil des derzeit angemeldeten Benutzer handelt.

Grüße
rubberman


Funktioniert 1A

Vielen Dankk nochmals!


Grüße

Jaglag