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:
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):
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
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:
von
Oder das hier:
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:
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:
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
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%
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
>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!
Oder das hier:
For /f "usebackq delims==. tokens=1-3" %%i IN (`set strArrayName`) DO Echo Array field number %%j have value %%k
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
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 101669
Url: https://administrator.de/contentid/101669
Ausgedruckt am: 17.11.2024 um 17:11 Uhr
6 Kommentare
Neuester Kommentar
Hallo anve!
Vorweg: Die Hilfe zu den einzelnen Befehlen kannst Du (am Beispiel "for") so aufrufen:
Zu
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
ermöglicht werden. Dadurch ändert sich die Variablenschreibweise von
auf
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):
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:
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
... womit noch die Frage
Grüße
bastla
Vorweg: Die Hilfe zu den einzelnen Befehlen kannst Du (am Beispiel "for") so aufrufen:
for /?
:: oder
help for
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
%Variable%
!Variable!
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
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%
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
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.
Edit: Ok ich war langsamer....
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....
Wenn du an der Eingabeaufforderung set /? eingibst erhälst du die Hilfe zum Set Befehl. Dort steht unter anderem:
Mit dem Forbefehl kansn tud eine Liste (aus einer Datei oder einem Verzeichnis) durchgehen.
Das geht entweder so:
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
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
<< >> - 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 (liste.txt) do echo %i
FOR /F "delims=" %i in ('dir /d /on /b') do echo %i
Hallo anve!
Ansonsten mit
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 [/Edit]
Eine weitere Frage hätte ich noch? Wann nehme ich
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.SET /A %i=0
und wannset Variable=%time%
wie hantle ich mich durch die ganzen Dateien in einem Ordner
Im einfachsten Fall (steht bei "for /?" ) mitfor %%i in ("D:\Dein Ordner\*.*") do echo "%%i"
for /f "delims=" %%i in ('dir /b /on /a-d "D:\Dein Ordner\*.*"') do echo "%%i"
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 [/Edit]