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-Key: 28010

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

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

Member: stpe
stpe Mar 12, 2006 at 19:59:57 (UTC)
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
Member: MacLeod
MacLeod Mar 12, 2006 at 20:10:03 (UTC)
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
Member: stpe
stpe Mar 12, 2006 at 20:37:49 (UTC)
Goto Top
Auf der Linux-Bash kann man zählen ;)

Nimm diese: link nicht mehr verfuegbar
Gruss
Stefan
Member: stpe
stpe Mar 12, 2006 at 20:46:49 (UTC)
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
Member: djbrandt
djbrandt Mar 12, 2006 at 20:56:30 (UTC)
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
Member: MacLeod
MacLeod Mar 12, 2006 at 20:58:52 (UTC)
Goto Top
Prima.
Das probiere ich morgen früh gleich mal.
Vielen Dank,
Peter
Member: stpe
stpe Mar 12, 2006 at 21:04:07 (UTC)
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
Member: Biber
Biber Mar 12, 2006 at 21:49:46 (UTC)
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
Member: MacLeod
MacLeod Mar 12, 2006 at 22:11:49 (UTC)
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
Member: Schirrmeister
Schirrmeister Mar 13, 2006 at 07:24:39 (UTC)
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%.
Member: MacLeod
MacLeod Mar 13, 2006 at 13:33:36 (UTC)
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
)
Member: Biber
Biber Mar 13, 2006 at 13:59:57 (UTC)
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
Member: Schirrmeister
Schirrmeister Mar 13, 2006 at 14:01:27 (UTC)
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.
Member: MacLeod
MacLeod Mar 13, 2006 at 14:27:03 (UTC)
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
Member: MacLeod
MacLeod Mar 13, 2006 at 20:09:15 (UTC)
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
Member: Biber
Biber Mar 13, 2006 at 20:31:52 (UTC)
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