anve
Goto Top

Zeit messen für das Erstellen einer RAR-Datei

Ich will die Zeit messen wie lange das zippen bzw. raren einer Datei bzw. aller Dateien eines Ordners dauert.

Hallo zusammen!

Ich habe folgenden ähnlichen Beitrage gefunden:
http://www.root-faq.de/Zeit_messen_zum_Erstellen_von_Dateien_mit_batch_ ...

Das ganze will ich aber nun verwenden um die Zeitdauer für das Zippen bzw. Raren einer Datei zu messen. Dazu habe ich mich mal mit der Thematik Batch-Dateien beschäftigt. Folgende Probleme habe ich dabei:

1) Wie kann ich die Zeit in eine Variable speichern?
2) Wie kriege ich alle Dateien eins Ordners in eine Variable (array)?
3) Wie berechne ich die benötigte Zeit aus?

[EDIT]: Laufzeit bzw. Dauer einer Batch ermitteln! kann schon mal die Zeit messen (wie genau?). Fehlt dann nur noch 2)
Ansonsten gehts hier weiter:[/EDIT]
Zu 1):
Folgende Bsp. habe ich probiert um der Lösung näher zu kommen:
@ECHO OFF
ECHO Beginn %date% - %time%
SET /A %begin=%time%
FOR /L %%j IN (1 1 2) DO (
	ping localhost -n 5 >nul
	ECHO %%j.te Schleife: %time%
)
SET /A %end=%time%
ECHO Ende %time%
ECHO %begin%

Zu "ECHO Beginn %date% - %time%":
Wie kann ich in einem Echo mehrere Ausgaben machen? In anderen Programmiersprachen macht man das meisten mit +
In diesem Fall wird %date% nicht ausgegeben. Das Konkattenieren funktioniert so weit, aber wenn ich "ECHO %%j.te Schleife: %time%" ausgebe, kommt immer dieselbe Zeit!?

Warum kann ich keine Zeit in eine Variable speichern?
SET /A %begin=%time%
Obiges funktioniert nicht, da ich die Meldung "ECHO ist ausgeschaltet (OFF)." bekomme bei "echo %begin%". In Batchdatei - Ziel Ordner aktueller Monat):
@for /F "tokens=1,2,3,4 delims=. " %%a in ('date /t') do set MONAT=%%c_%%b_%%a  
echo %MONAT%
Damit kriege ich das Datum in einer Variable, aber ich verstehe nicht wie das funktionieren soll. Nirgends ist c, b oder a definiert? Tokens bedeutet anscheinend die Schleifennr. (so hab ich es zumindest verstanden). Delims ist irgendwie der Platzhalter nach dem getrennt wird. Aber was ist wenn ich mehr brauche als diese drei Buchstaben (c, b, a)? Andere Buchstaben funktionieren anscheinend nicht. Ich hab das ganze natürlich auf time umgeschrieben. Aber ich will eigentlich %time% haben, da dies viel genauer ist. Dies wiederum geht nicht in den Klammern ('xxxx'). Gibt es nicht eine einfachere Methode?

Ich will Stunde, Minute, Sekunde, Hundertstel um die Genauigkeit zu erhöhen. Dabei frage ich mich wo die Genauigkeitsgrenze liegt. Wenn ich zweimal %time% ausführe, dann ist ja schon ein Unterschied im Hundertstel-Bereich normalerweise (hier nicht!?). Außerdem denke ich mir, dass Batch-Datein den geringsten Overhead haben als ein externes Programm. Was meint ihr dazu? Lediglich die aufrufe von WinRar & Co. bringen eine Verzögerung mit sich.

Zu 2):
Mit
dir /d /on /b > liste.txt
bekomme ich die gewollte Liste. Wie kriege ich jetzt das in eine Variable? Welche Variablen werden im Batch-Modus überhaupt angeboten? Was ich so gesehen habe, gibt es keine Arrays! Nur Pseudo-Arrays bzw. Abhilfen wie das hier:
>for %i in (1,2,3) do @set var%i
var1=Das ist
var2=nur ein
var3= Pseudoarray
.......und so bewirke ich, das zuerst "%i" aufgelöst wird zu 1,2,3 und dann %var1%, %var2%, %var3%:  
>for %i in (1,2,3) do @echo !var%i!
von

Oder das hier:
For /f "usebackq delims==. tokens=1-3" %%i IN (`set strArrayName`) DO Echo Array field number %%j have value %%k  
von http://www.msfn.org/board/lofiversion/index.php/t47265.html

Aber ich verstehe nicht wie das funktioniert... Was bedeutet tokens=1,2,* oder tokens=1-3 ? usw.

Zu 3):
Am einfachsten wäre es, wenn ich es so machen könnte:
SET /A %begin=%time%
xxx
SET /A %end=%time%
ECHO end-begin

Aber das geht so ja nicht. In http://www.root-faq.de/Zeit_messen_zum_Erstellen_von_Dateien_mit_batch_ ... wird es folgendermaßen gemacht:
SET /A return="((hours * 60 + mins) * 60 + secs) * 100 + csec"  


Ich hoffe Ihr könnt mir weiterhelfen.

LG
anve

PS: Hilfreiche Seiten:
http://www.admini.de/batch-infos.htm
http://de.wikibooks.org/wiki/Batch-Programmierung/_Druckversion#Allgeme ...
http://www.computerhope.com/batch.htm

Content-ID: 101669

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

Ausgedruckt am: 17.11.2024 um 17:11 Uhr

bastla
bastla 12.11.2008 um 21:35:21 Uhr
Goto Top
Hallo anve!

Vorweg: Die Hilfe zu den einzelnen Befehlen kannst Du (am Beispiel "for") so aufrufen:
for /?
:: oder
help for
Zu
1) Wie kann ich die Zeit in eine Variable speichern?
So, wie auch jeden anderen String (die CMD-Shell kann nur mit ganzzahligen Werten rechnen, sodass die Zeitangabe ohnehin nicht unmittelbar zu verarbeiten ist):
set Variable=%time%

Dein Schleifenbeispiel scheitert daran, dass Variablen in Batch grundsätzlich nur einmalig am Beginn eines Blockes (wie eben einer "for"-Schleife oder eines "if"-Konstruktes) durch ihren Inhalt ersetzt ("aufgelöst") werden - soll dies auch innerhalb des Blockes erfolgen, so kann dies durch
setlocal enabledelayedexpansion
ermöglicht werden. Dadurch ändert sich die Variablenschreibweise von
%Variable%
auf
!Variable!
was den unangenehmen Nebeneffekt mit sich bringt, dass "!" als Variablenbegrenzer (und nicht mehr als gewöhnliche Zeichen) interpretiert werden (und damit aus dem Variableninhalt "verschwinden", und falls sie paarweise auftreten, den dazwischen liegenden Text zumeist gleich "mitnehmen", da dieser Text als Variablenname verstanden wird und der Interpreter versucht, ihn durch seinen Wert zu ersetzen).

Zum tatsächlichen Rechnen mit den gespeicherten Werten für Beginn- und Endzeit hast Du ja schon eine passende Formel gefunden - diese wandelt die Zeitangabe in Hundertstelsekunden um.

Um allerdings die einzelnen Bestandteile ("tokens") der Zeit (also h, m, s und c) zu erhalten, muss der Zeitstring mittels "for /f"-Schleife aufgespalten werden (wobei als Trennzeichen = "delimiter" Doppelpunkt und Komma dienen):
for /f "tokens=1-4 delims=:," %%a in ("%time%") do echo Stunden: %%a Minuten: %%b Sekunden: %%c Hundertstelsekunden: %%d
Der erste Bestandteil wird der (angegebenen) Schleifenvariablen %%a zugewiesen, für die weiteren "tokens" geht es einfach alphabetisch weiter (%%b bis %%d).

Damit die Berechnung dann aber nicht zu einfach wird, gibt es noch eine kleine Hürde zu überweinden: Mit der Ziffer 0 beginnende Zahlenwerte werden als Oktalzahlen interpretiert, was für 00 bis 07 unproblematisch ist, für 08 und 09 aber (begreiflicher Weise) zu einem Fehler führt - Lösung: Setze vor die (zweistellige) Zahl eine 1 (wodurch etwa "109" entsteht) und subtrahiere 100, sodass nur noch die /Dezimal-)Zahl (9) als Ergebnis verbleibt.

Daraus folgt etwa folgender Code für eine Zeitberechnung:
@echo off & setlocal enabledelayedexpansion
echo Beginn %date% - %time%
set begin=%time%
for /L %%j in (1 1 2) do (
	ping localhost -n 5 >nul
	echo %%j.te Schleife: !time!
)
set end=%time%
echo Ende %date% - %end%

for /f "tokens=1-4 delims=:," %%a in ("%begin%") do set /a BTime=((%%a * 60 + (1%%b-100)) * 60 + (1%%c-100)) * 100 + 1%%d-100  
for /f "tokens=1-4 delims=:," %%a in ("%end%") do set /a ETime=((%%a * 60 + (1%%b-100)) * 60 + (1%%c-100)) * 100 + 1%%d-100  

set /a Dauer=ETime - BTime
if %Dauer% lss 0 set /a Dauer+=8640000

echo\
echo Dauer in Hundertstelsekunden: %Dauer%
set /a s=Dauer / 100
set /a c=100 + Dauer %% 100
echo Dauer in Sekunden: %s%,%c:~-2%
Um den Nachkommaanteil in der letzten Zeile zweistellig ausgeben zu können, wird dieser wiederum durch Hinzufügen von 100 in den dreistelligen Bereich gebracht und durch Bildung des Teilstrings "letzte 2 Zeichen" bei Bedarf mit führender Null erzeugt.
Damit sollte
3) Wie berechne ich die benötigte Zeit aus?
weitgehend abgedeckt sein, ...
... womit noch die Frage
2) Wie kriege ich alle Dateien eins Ordners in eine Variable (array)?
bliebe - diese allerdings animiert gleich zur Gegenfrage: "Wozu ein Array?" ( - das gibt es nämlich, wie Du schon herausgefunden hast, in CMD tatsächlich nicht.)

Grüße
bastla
miniversum
miniversum 12.11.2008 um 21:41:20 Uhr
Goto Top
Da hast du mehrere Dinge nicht richtig (verstanden).
1. delims und tokens beim For:
Delims gibt die Trennzeichen an.
Tokens sind die Elemente (die durch die Trennziechen getrennt werden) die du haben willst.
Hier ein Paar Beispiele:
FOR /F "tokens=1,2,3 delims=:" %%i in ('echo x:y:z') do echo [%%i] [%%j] [%%k]
FOR /F "tokens=2 delims=:" %%i in ('echo x:y:z') do echo [%%i] [%%j] [%%k]
FOR /F "tokens=1,3 delims=:" %%i in ('echo x:y:z') do echo [%%i] [%%j] [%%k]
2. SET /A %end=%time% funktioniert nicht. Wenn dann SET end=%time%
3. Variabeln in einer klamer (in for oder in if) werden zu beginn des geklammerten blockes aufgelöst. Darin werden sie nicht aktualisiert. Bei for hilft hier meistens der Aufruf einer Unterprozedur mit Übergabe des Variabeln aus For mit "call". In der Unterprozedur werden dann die Vatiabeln wieder aufgelöst. Alternativ könnte man enabledelayedexpansion nutzen (siehe der befehl setlocal). dann muß man die variabeln allerdings mit ! statt mit % markieren.
4. Das errechnen der Zeitdifferenz:
Der Ansatz ist das aufnahmen der Beginnzeit, dann die Aktion, dann das aufnehmen der Endzeit. Danach das verrechnen jeder einzelnen Zeit.
@echo off
FOR /F "tokens=1,2,3,4 delims=:, " %%i in ('echo %time%') do set "starth=%%i" & set "startm=%%j" & set "starts=%%k" & set "starths=%%l"  
rem hier dann die Aktion
pause
rem hier ende der Aktion
FOR /F "tokens=1,2,3,4 delims=:, " %%i in ('echo %time%') do set "endh=%%i" & set "endm=%%j" & set "ends=%%k" & set "endhs=%%l"  


set /a divhs=endhs-starths
if %divhs% lss 0 (
set /a divhs=divhs+100
set /a ends=ends+1
)

set /a divs=ends-starts
if %divs% lss 0 (
set /a divs=divs+60
set /a endm=endm+1
)

set /a divm=endm-startm
if %divm% lss 0 (
set /a divm=divm+60
set /a endh=endh+1
)

set "T="  
set /a divh=endh-starth
if %divh% lss 0 (
set /a divh=divh+24
set "T=1:"  
)


echo %T%%divh%:%divm%:%divs%:%divhs%
pause

Edit: Ok ich war langsamer....
anve
anve 14.11.2008 um 11:23:36 Uhr
Goto Top
Hallo ihr!

Vielen Dank für eure hilfreichen Erklärungen!

Eine weitere Frage hätte ich noch? Wann nehme ich
SET /A %i=0
und wann
set Variable=%time%

Zitat von @bastla:
... womit noch die Frage
>2) Wie kriege ich alle Dateien eins Ordners in eine Variable
(array)?
bliebe - diese allerdings animiert gleich zur Gegenfrage: "Wozu
ein Array?" ( - das gibt es nämlich, wie Du schon
herausgefunden hast, in CMD tatsächlich nicht.
)

Ich brauche ja nicht unbedingt ein Array, aber wie hantle ich mich durch die ganzen Dateien in einem Ordner (muss nicht rekursiv sein) durch? Schon klar mit einer for-Schleife aber wie mache ich das?

Das müsste wahrscheinlich so irgendwie gehen (aber ohne es jetzt als Datei auszugeben):
dir /d /on /b > liste.txt

Oder wäre die einzige Möglichkeit das als Datei auszugeben, wieder einzulesen und die Anzahl der Zeilen zu zählen und anschließend Zeile für Zeile durchgehen?

LG
anve
miniversum
miniversum 14.11.2008 um 11:43:06 Uhr
Goto Top
Wenn du an der Eingabeaufforderung set /? eingibst erhälst du die Hilfe zum Set Befehl. Dort steht unter anderem:
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

          Wenn Sie einen der arithmetischen oder Moduloperatoren verwenden, müssen
          Sie die Zeichenfolge für den Ausdruck in Anführungszeichen setzen. Alle
          nicht-nummerischen Zeichenfolgen im Ausdruck werden als Zeichenfolgen von
          Umgebungsvariablen behandelt, deren Werte vor der Verwendung in Zahlen
          konvertiert werden. Wenn eine Umgebungsvariable angegeben wird, die nicht
          definiert ist, wird für diese der Wert Null verwendet. Somit können Sie
          mit Umgebungsvariablen Berechnungen vornehmen, ohne %-Zeichen einzugeben,
          um deren Werte zu erhalten. Wenn der Befehl SET /A von der Befehlszeile,
          d.h. außerhalb eines Befehlsskripts ausgeführt wird, dann zeigt er
          den endgültigen Wert des Ausdrucks an. Der Zuordnungsoperator erfordert
          eine Umgebungsvariable auf der linken Seite des Operators. Nummerische Werte
          stellen immer Dezimalzahlen dar, es sei denn, sie haben ein Präfix 0x für
          hexadezimale Zahlen, 0b für binäre Zahlen oder 0 für oktale Zahlen. Damit
          stellt 0x12 dieselbe Zahl wie 18 oder 022 dar. Beachten Sie, dass die oktale
          Schreibweise verwirrend sein kann: So sind 08 und 09 keine gültigen Zahlen,
          da 8 und 9 keine erlaubten oktalen Ziffern sind.

Mit dem Forbefehl kansn tud eine Liste (aus einer Datei oder einem Verzeichnis) durchgehen.
Das geht entweder so:
FOR /R x:\Pfad %i IN (*.*) DO echo %i
oder so:
dir /d /on /b > liste.txt
FOR /F "delims=" %i in (liste.txt) do echo %i
oder abgekürzt:
FOR /F "delims=" %i in ('dir /d /on /b') do echo %i
bastla
bastla 14.11.2008 um 11:44:58 Uhr
Goto Top
Hallo anve!

Eine weitere Frage hätte ich noch? Wann nehme ich
SET /A %i=0
und wann
set Variable=%time%
Die Antwort solltest Du eigentlich mit "set /?" schon gefunden haben: "/A" steht für "arithmetisch" - dies dann, wenn eine Berechnung vorgenommen oder zumindest darauf hingewiesen werden soll, dass eine numerische Variable gemeint ist.

wie hantle ich mich durch die ganzen Dateien in einem Ordner
Im einfachsten Fall (steht bei "for /?" face-wink) mit
for %%i in ("D:\Dein Ordner\*.*") do echo "%%i"
Ansonsten mit
for /f "delims=" %%i in ('dir /b /on /a-d "D:\Dein Ordner\*.*"') do echo "%%i"
Das "delims=" ersetzt die Standardtrennzeichen Leerzeichen und TAB durch "Nichts", wodurch der Dateiname nicht nur bis zum ersten enthaltenen Leerzeichen in %%i übernommen wird - deshalb dann auch die Anführungszeichen, da ja in %%i so auch ein oder mehrere Leerzeichen enthalten sein können (was zwar für "echo" egal wäre, nicht allerdings für "ren", "copy", "move", etc).

Die "for /f"-Variante ist dann sinnvoll (bzw notwendig), wenn Du eine Sortierung benötigst oder eine Einschränkung (wie hier: "/a-d" für "keine Verzeichnisse") vornehmen willst.

Grüße
bastla

[Edit] @miniversum 1:1 face-wink [/Edit]
anve
anve 14.11.2008 um 18:51:46 Uhr
Goto Top
Ein herzliches Dankeschön an miniversum & bastla!

Ihr habt mir wirklich geholfen! Die Antworten kamen auch immer gleich! Ihr seid toll!

GLG
anve