macleod
Goto Top

Zählerfunktion in Batch Datei

Sortieren von Dateien

Hallo.
Ich stehe vor einem für euch wahrscheinlich trivialen Problem. Eingehende Dateien auf einem FTP (lokal) sollen anhand von einem String in der Datei in entsprechende Unterverzeichnisse verschoben/kopiert werden. Habe hier schon etwas umhergelesen und einen Teilerfolg erzielt:
del temp.txt
SET LAUFN=0001
dir k:\_incoming\ /s /b |find "%LAUFN%" > temp.txt
FOR /f "eol=; tokens=1,2* delims=," %%i IN (temp.txt) DO @xcopy "%%i" k:\test\%LAUFN%\ /y
Nun soll dieser Ablauf aber mehrmals durchgeführt werden und zwar mit 0001, 0002, 0003 und so weiter. Ideal wäre die Angabe über Startnummer/Schrittweite/Endnummer. Duchläufe gehen bis zu 100.000 face-confused Der Zeitaspekt ist aber Nebensache.
Mein Betriebssystem ist Win2003SP1 und bei den Datein handelt es sich um reine Binärdateien, kein Text oder ähnliches.
Ich bin für jeden Tipp dankbar.
Gruß,
Peter

Content-ID: 28010

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

Ausgedruckt am: 23.11.2024 um 16:11 Uhr

stpe
stpe 12.03.2006 um 20:59:57 Uhr
Goto Top
Leider können Batch-Dateien nicht rechnen oder zählen. Eine Lösung ist über einen kleinen Umweg möglich:

Lege eine Datei an, in der alle laufenden Zahlen Zeile für Zeile stehen, also:
0001
0002
0003
...
Dann kannst Du diese Datei in einer For-Schleife "durchzählen" lassen:

for /F %%z in (nummern.txt) do for FOR /f "eol=; tokens=1,2* delims=," %%i IN (temp.txt) DO @xcopy "%%i" k:\test\%z%\ /y  

Ich hoffe, ich konnte helfen.
Stefan
MacLeod
MacLeod 12.03.2006 um 21:10:03 Uhr
Goto Top
Hmmm. Für kleinere Zahlenbereiche ist diese Idee optimal. Aber bei bis zu 100000 Zahlen recht mühsam. Außer ich bastel mir ein Script, welches diese Nummerndatei automatisch erzeugt.
Vielen Dank erstmal.
Gruß,
Peter

Edit: Funktioniert leider nicht. Denn erst wird anhand der Such-Zahl die Liste der betreffenden Dateien gebildet (temp.txt) und dann kopiert. Mit einer neuen Such-Zahl muss auch wieder erst eine neue temp.txt erstellt werden. Ich glaube ich bräuchte eine echte Schleife in der Batch selbst.
So etwa:

:Start
Laufnummer = Laufnummer +1
Prüfe ob Laufnummer = Endnummer dann GOTO :EXIT
Konvertiere Laufnummer zu Laufvariable
"Kopierfunktion komplett"
GOTO :START
: EXIT
stpe
stpe 12.03.2006 um 21:37:49 Uhr
Goto Top
Auf der Linux-Bash kann man zählen ;)

Nimm diese: link nicht mehr verfuegbar
Gruss
Stefan
stpe
stpe 12.03.2006 um 21:46:49 Uhr
Goto Top
Hatte Deinen Edit gerade erst gelesen.

Integrier die Erstellung der temp.txt mit Deiner for-Schleife in eine Sub-Routine. Diese lässt Du von der "Ich zähl bis 100.000"-Schleife immer anspringen.

Habe gerade leider kein Windows zur Verfügung, aber das Konstrukt koennte dann in etwa so aussehen:

for /F %%z in (nummern.txt) do call :kopieren
goto ende

:kopieren
   dir k:\_incoming\ /s /b |find "%z%" > temp.txt  
   FOR /f "eol=; tokens=1,2* delims=," %%i IN (temp.txt) DO @xcopy "%%i" k:\test\%z%\ /y  
   return

:ende
djbrandt
djbrandt 12.03.2006 um 21:56:30 Uhr
Goto Top
Hi,

mit set /A läßt sich bei XP rechnen

Die /A-Option gibt an, dass die Zeichenfolge rechts vom Gleichheitszeichen
ein nummerischer Ausdruck ist, der ausgewertet wird. Das Auswertungsprogramm
des Ausdrucks unterstützt dabei die folgenden Vorgänge, entsprechend ihrer
Anordnung mit abnehmendem Vorrang:

() - Gruppierung
! ~ - - monäre Operatoren
          • / % - arithmetische Operatoren
          + - - arithmetische Operatoren
          << >> - logische Verschiebung
          & - bitweise UND
          ^ - bitweise exklusives ODER
          | - bitweise ODER
          = *= /= %= += -= - Zuordnung
          &= ^= |= <<= >>=
          , - Trennzeichen für Ausdrücke


          Damit kannst Du Deine Schleifen bauen

          set /A bla=1
          1
          set /a bla=%bla%+1
          2
          echo %bla%
          2
          set /a bla=%bla%+1
          3
          echo %bla%
          3


          Gruß

          Dieter
MacLeod
MacLeod 12.03.2006 um 21:58:52 Uhr
Goto Top
Prima.
Das probiere ich morgen früh gleich mal.
Vielen Dank,
Peter
stpe
stpe 12.03.2006 um 22:04:07 Uhr
Goto Top
Habe nie mit XP gearbeitet, vorher ging das nicht. Man lernt immer dazu.

Danke und 5 Sternchen dafür face-smile

Gruss
Stefan
Biber
Biber 12.03.2006 um 22:49:46 Uhr
Goto Top
Hmm,
Im Batch lässt sich schon hochzählen und rechnen.

Und wie man/frau aus einer Zählvariablen (1,2,3...) einen formatierten Text macht ("0001", "0002", ..) hab ich u.a. in dem Batch-Tut II ("Ein bisschen Handwerkszeug..") beschrieben.

Aber die Mimik selbst ist mir bei Dir noch nicht klar, MacLeod.
Bei Dir sind im Incomingverzeichnis immer Dateien, die ein "0058"..."0077", "0013" im Namen haben? Oder wie muss ich mir das vorstellen?

Rückfragend
Biber
MacLeod
MacLeod 12.03.2006 um 23:11:49 Uhr
Goto Top
Hallo.
Die Dateien haben den String leider nicht im Namen sondern im Binärcode. Der Dateinamen kann irgendeine beliebige Form und Endung haben.
Gruß,
Peter
Schirrmeister
Schirrmeister 13.03.2006 um 08:24:39 Uhr
Goto Top
Will doch auch meinen Senf dazugeben...
Du sagst, Du brauchst die Zählernummer mit führenden Nullen, dann würde ich die äußere Zählerschleife so machen:
setlocal enableextensions

for /L %%i in ( 1, 1, 100000 ) do (
&nbsp;&nbsp;&nbsp;&nbsp;set LAUFN=00000%%i
&nbsp;&nbsp;&nbsp;&nbsp;set LAUFN=!LAUFN:~-6!
&nbsp;&nbsp;&nbsp;&nbsp;...
)

endlocal

Die Ausrufezeichen (statt %) sind nötig, damit die Variable jedesmal neu ausgewertet wird, dafür ist auch das enableextensions.
Bei der weiteren Verwendung mußt Du dann auch !LAUFN! schreiben, statt %LAUFN%.
MacLeod
MacLeod 13.03.2006 um 14:33:36 Uhr
Goto Top
Hallo.
Ich bekomme es nicht hin. Er zählt zwar durch was man am set LAUFN... noch sieht, aber mit echo bekomme ich nie etwas angezeigt. Und auch beim dir/find steht dann nichts drin. Habe alle möglichen Variationen durchprobiert. Hat noch jemand eine Idee?
Danke,
Peter

setlocal enableextensions
for /L %%k in ( 1, 1, 10 ) do (
del temp.txt
set LAUFN=00000%%k
set LAUFN=!LAUFN:~-6!
echo !%LAUFN%
dir k:\_incoming\ /s /b |find "!LAUFN!" > temp.txt
FOR /f "eol=; tokens=1,2* delims=," %%i IN (temp.txt) DO @xcopy "%%i" k:\test\%LAUFN%\ /y
)
Biber
Biber 13.03.2006 um 14:59:57 Uhr
Goto Top
Moin MacLeod,

das sind ja zweieinhalb Probleme, die da drin sind.
1) die formale Syntax
2) die "0000x" im Binärcode statt im Namen
2,5) die Fehlermeldung, wenn keine Datei mit "0000x" gefunden (das halbe Problem)

ad 1) So ist es formal richtig (mit der LAUFN-Variable; Rest ausgeREMt):
 @echo off & setlocal enabledelayedexpansion
for /L %%k in ( 1, 1, 10 ) do ( 
    rem echo del temp.txt 
    set "LAUFN=00000%%k"  
    set "LAUFN=!LAUFN:~-6!"   
    echo !LAUFN!
    rem dir k:\_incoming\ /s /b 2>nul |find "!LAUFN!" >temp.txt   
    rem FOR /f "eol=; tokens=1,2* delims=," %%i IN (temp.txt) DO @xcopy "%%i" k:\test\%LAUFN%\ /y   
)  
ad 2)
mit dem "DIR K:\incoming /s /b .." werden Dir doch nur Dateinamen geliefert.
Wenn das "0000x" aber in den Dateien selbst enthalten ist, musst Du auch die Dateien selbst mit Find durchsuchen.
Und abhängig von "Gefunden"=Errorlevel 0 bzw. Errorlevel 1 ="nicht gefunden" diese Datei kopieren.

ad 2,5)
dir k:\_incoming\ /s /b 2>nul |find "!LAUFN!" >temp.txt
...mit 2>nul die DIR-Nicht-gefunden-Meldung entsorgen


Gruß
Biber
Schirrmeister
Schirrmeister 13.03.2006 um 15:01:27 Uhr
Goto Top
Dein echo ist ja auch nicht korrekt, ich sagte doch, Du musst dann IMMER ! nehmen.
Wenn Du %LAUFN% hinschreibst, wird das ausgewertet, bevor die Schleife ausgeführt wird, und da ist die Variable noch nicht gesetzt.
MacLeod
MacLeod 13.03.2006 um 15:27:03 Uhr
Goto Top
Stimmt. Ihr habt natürlich recht!
Er sucht nur in Dateinamen. Habe vor lauter Bäumen den Wald nicht mehr gesehen.
Also müsste ich erst das Dir in eine Liste -> jede Datei nach String durchsuchen und bei Treffer ab in eine zweite Liste -> Kopieren.
Jetzt überlege ich, ob man das Problem nicht besser in einem echten Compiler aufdröselt. Das altbewährte Powerbasic wäre wohl ideal dafür. Da kann ich dann auch schneller mehr Schicki-micki einbauen, wenn mir noch etwas einfällt.
Ich danke euch allen erst mal ganz herzlich.
Gruß,
Peter
MacLeod
MacLeod 13.03.2006 um 21:09:15 Uhr
Goto Top
Erfolg!
Es geht auch ohne Powerbasic:

@echo off & setlocal enabledelayedexpansion
for /L %%k in ( 1, 1, 5 ) do (
del temp.txt
set "LAUFN=00000%%k"
set "LAUFN=!LAUFN:~-6!"
echo !LAUFN!
FINDSTR /s /m /C:"!LAUFN!" k:\_incoming\*.* > temp.txt
FOR /f "eol=; tokens=1,2* delims=," %%i IN (temp.txt) DO @xcopy "%%i" k:\test\!LAUFN!\ /y /f /r
)
endlocal
pause

Danke nochmal,
Peter
Biber
Biber 13.03.2006 um 21:31:52 Uhr
Goto Top
Glückwunsch, MacLeod,

nur für die kommenden Jahre der Pflege und Wartung Deines Batches (weil Du bestimmt in drei Monaten nicht mehr weißt, ob da alle Schalter einen Sinn machen):


...
FINDSTR /s /m /C:"!LAUFN!" k:\_incoming\*.* > temp.txt
... geht in diesem Fall sicher besser als mit Find.exe.
Der Befehl würde auch Dateien mit Leerzeichen oder mit Kommata im Namen finden.

---> Dann aber muss der FOR-Befehl die auch entgegennehmen wollen:

Bisher:
FOR /f "eol=; tokens=1,2* delims=," %%i IN (temp.txt) DO @xcopy "%%i" k:\test\!LAUFN!\ /y /f /r

> ein "eol=;" KANN nie benötigt werden.
> ein "tokens="1,2* delims=," macht auch keinen Sinn, wenn tatsächlich ein Komma im Namen sein könnte. Dann wird der XCOPY nichts finden.

Demnach reicht vollkommen:
FOR /f "delims=" %%i IN (temp.txt) DO xcopy "%%i" k:\test\!LAUFN!\ /y /f /r


Ist ein bisschen wartbarer, denke ich.

Gruß
Biber