Führende Null für Stapelskript mit% time% -Variable erforderlich

26

Ich bin auf einen Fehler in meinem DOS-Skript gestoßen, der Datums- und Zeitdaten für die Benennung von Dateien verwendet. Das Problem war, dass ich eine Lücke hatte, weil die Zeitvariable für Stunde <10 nicht automatisch die führende Null lieferte. Also gibt echo% time% zurück: '9: 29: 17.88'.

Kennt jemand eine Möglichkeit, führende Nullen bedingt aufzufüllen, um dies zu beheben?

Weitere Informationen: Mein Befehl zum Festlegen des Dateinamens lautet:

set logfile=C:\Temp\robolog_%date:~-4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log

Dies endet mit: C: \ Temp \ robolog_20100602_ 93208.log (um 9:23 Uhr morgens).

Diese Frage hängt mit dieser zusammen .

Vielen Dank

Ira
quelle
Es ist möglich, einen aufgefüllten Stundenwert zu erhalten ... FOR / F "TOKENS = 1 DELIMS =:" %% A IN ('TIME / T') SETZE HH = %% A und ersetze dann% time: ~ 0,2% Mit% HH% hatte ich mir eine kompaktere Lösung erhofft, aber das wird funktionieren.
Ira
Eine "kompaktere" Lösung wäre etwas in einer anderen Sprache (Powershell-Python-Perl-WSH).
Grawity
Umgestellt, um Jesses Antwort als die von mir verwendete Lösung zu markieren. Es funktioniert sowohl mit Pre-Noon-Zeiten zum Auffüllen mit führender 0 als auch mit Post-Noon-Militärzeit.
Ira

Antworten:

60

Eine sehr einfache Möglichkeit besteht darin, das führende Leerzeichen einfach durch Null zu ersetzen
echo %TIME: =0%
:
09:18:53,45

Jesse
quelle
1
Es klappt! Dies ist die einfachste Lösung, die ich denke ..
Aerobrain
Kann man das auch mit mehreren Zeichen machen? iE all ',', '' und ':'. Momentan erstelle ich Zwischenvariablen, aber das funktioniert natürlich nur aufgrund der wenigen Ersetzungen. Für mehr wäre es umständlich.
Devolus
1
Ich verwende diese in einem zweiten „Schritt“ , um die Stunden zu ändern: set HH=%time:~-11,2% set MM=%time:~-8,2% set SS=%time:~-5,2% set ISOTIME=%HH: =0%-%MM%-%SS% echo %ISOTIME%Siehe auch ss64.com/nt/syntax-replace.html
Griff
+1 Dies ist die kürzeste / beste Antwort. Wie ich es benutzt habe: set timestring=%TIME: =0%Früh im Sub Call - dann arbeite ich timestringstattdessen mit (oder mit welcher Variablen auch immer).
bshea
14

Meine Lösung bestand darin, die folgende Idee zu verwenden:

SET HOUR=%TIME:~0,2%
IF "%HOUR:~0,1%" == " " SET HOUR=0%HOUR:~1,1%
Neil Ratcliffe
quelle
Ich mag das. Einfach und intuitiv.
Ken
Funktioniert unter modernen Fenstern, gibt aber auf Server 2003 einen Syntaxfehler aus!
Dr. BDO Adams
Funktioniert einwandfrei ab 2008, eleganteste Lösung. Vielen Dank.
Bjoster
1
but gives syntax error on server 2003- warum interessiert dich das im Jahr 2016?
Marcin Orlowski
Perfekt für Windows 10-Eingabeaufforderung
Mike Upjohn
5

Eine ähnliche Idee wie Dennis 'Antwort . Das Problem ist, dass die Breite von %time%immer gleich ist, sodass am Anfang ein Leerzeichen eingefügt wird, anstatt eine kürzere Zeichenfolge zurückzugeben.

Sie können das loswerden mit for:

for /f "delims= " %x in ("%time%") do set T=0%x

Der Rest ist dann mehr oder weniger gleich.

Joey
quelle
2
Diese Lösung funktioniert für> 10, erstellt aber jetzt '010' für 10: ...
Devolus
3
Die Antwort von Jesse ist die richtige ...
Simon Sobisch
Dies ist eine sehr schlechte Antwort, sie bricht zusammen, sobald es zwei Ziffern in der Stunde gibt. Ich kann nicht glauben, dass das OP es ausgewählt hat.
Thebunnyrules
3

Ich habe gerade mit Jesse's Contribution eine Variable mit der geänderten Ausgabe erstellt. Dann beziehe ich mich auf diese Variable, um den Stundenanteil zu bilden.

set NantTime=%time: =0%
nant\bin\nant.exe -nologo+ -debug+ -verbose+ -D:project.config=debug /f:build\default.build -l:logs\architect-build-%DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2%-%NantTime:~0,2%-%time:~3,2%-%time:~6,2%.log 
pause

Mit der Originalquelle:

set hour=%time: =0%
set logfile=C:\Temp\robolog_%date:~-4%%date:~4,2%%date:~7,2%_%hour:~0,2%%time:~3,2%%time:~6,2%.log

Danke Jesse. Ich hätte abgestimmt, wenn ich die Reputationspunkte hätte.

Ben Newcomb
quelle
1

Für die kompakteste Lösung, die alles oben umsetzt, denke ich das

FOR / F TOKENS = 1-4 DELIMS = / %% A IN (% DATE%) DO FOR / F TOKENS = 1-3 DELIMS = :. %% E IN ("% TIME: = 0%") SETZE Protokolldatei = C: \ Temp \ robolog _ %% D %% C %% B _ %% E %% F %% G.log

würde hier funktionieren, ohne dem Skript neue Zeilen hinzuzufügen. Es ist jedoch vielleicht weniger elegant als Lösungen mit mehreren Befehlen.

Jerry
quelle
1

Das Folgende braucht ein paar Zeilen mehr, ist aber klar und verständlich. Es speichert stdout und stderr in separaten Dateien mit jeweils einem Zeitstempel. Der Zeitstempel enthält Jahr, Monat, Tag, Stunde, Minute und Sekunde in dieser Reihenfolge. Zeitstempel sollten immer die höchstwertige Datumskomponente zuerst (Jahr) und die niedrigste Komponente (Sekunden) zuletzt haben. Auf diese Weise können die Dateien in zeitlicher Reihenfolge aufgelistet werden. Hier ist ohne weiteres meine Lösung.

:prepare time stamp 
set year=%date:~10,4%
set month=%date:~4,2%
set day=%date:~7,2%
set hour=%time:~0,2%
:replace leading space with 0 for hours < 10
if "%hour:~0,1%" == " "  set hour=0%hour:~1,1%
set minute=%time:~3,2%
set second=%time:~6,2%
set timeStamp=%year%.%month%.%day%_%hour%.%minute%.%second%

:run the program 
ProgramName.pl 1> RunLogs\out.%timeStamp% ^
               2> RunLogs\err.%timeStamp%
David
quelle
0

Dies setzt eine Null auf den Beginn der Zeit und nimmt die letzten beiden Ziffern der Stunde (die Startpositionen für Minute und Sekunde sind um eins verschoben). So wird 3 Uhr morgens "03", dann "03" und Stunde 15 wird "015", dann "15".

set T=0%time%
set T=%T:~1,2%%T:~4,2%%T:~7,2%
set D=%date:~-4%%date:~4,2%%date:~7,2%
set logfile=C:\Temp\robolog_%D%_%T%.log

Weniger lesbar:

set T=0%time%
set logfile=C:\Temp\robolog_%date:~-4%%date:~4,2%%date:~7,2%_%T:~1,2%%T:~4,2%%T:~7,2%.log
Bis auf weiteres angehalten.
quelle
1
Ich bin mir nicht sicher, ob das funktioniert. Wenn ich 'set T = 0% time%' ausführe und es 9:38 Uhr ist, gibt echo% T% zurück: '0 9: 38: 54.21', dann wird mit% T: ~ 1,2% das Leerzeichen abgerufen, kein Anführungszeichen 0.
Ira
0

Eine Codezeile wird tun, was Sie brauchen:

    IF "%Time:~0,1%" == " " SET TimeStamp=0%Time:~1,7%

Beispielsweise verwende ich% Date% und füge dann einer Variablen, die ich verwende, eine führende Null hinzu, um zu bestimmen, ob ich das führende Leerzeichen für% Time% durch eine Null ersetzen muss.

    ::Prepare TimeStamp variable by replacing leading space with 0 for Hours < 10
    SET TimeStamp=%Time:~0,8%
    IF "%Time:~0,1%" == " " SET TimeStamp=0%Time:~1,7%
    Echo Started on %Date$ at %TimeStamp%

    :: Insert what you are doing here...

    SET TimeStamp=%Time:~0,8%
    IF "%Time:~0,1%" == " " SET TimeStamp=0%Time:~1,7%
    ECHO Finished on %Date% at %TimeStamp%
Richard Wright
quelle
0

Dadurch wird ein sortierbarer Zeitstempel erstellt, und in der zweiten Zeile wird sichergestellt, dass keine Leerzeichen für einstellige Stunden usw. vorhanden sind, um die Verwendung für Skripte zu ermöglichen:

set datestamp=%date:~-4%.%date:~-10,-8%.%date:~-7,-5%_%time:~0,2%.%time:~3,2%.%time:~6,2%
set datestamp=%datestamp: =_%

Ausgabe:

2018.02.26__9.47.34

Muposat
quelle
0

Dank der Hilfe von oben ... Dies ist, was ich benutze:

C:\Windows\System32>SET short=%date:~10,4%-%date:~4,2%-%date:~7,2%
C:\Windows\System32>ECHO -- Short Date: %short%
-- Short Date: 2018-06-27
C:\Windows\System32>SET long=%date:~10,4%-%date:~4,2%-%date:~7,2%_%time:~0,2%_%time:~3,2%_%time:~6,2%
C:\Windows\System32>ECHO -- Long Date: %long%
-- Long Date: 2018-06-27_10_51_43

Ich habe dann Protokolle, die in Robocopy-Jobs wie folgt aufgerufen werden:

Es gibt viele davon:

Robocopy C:\Users\ME\Favorites\ %usb%:\Local_PC\Favorites\ /MIR /TEE /FFT /DST /TIMFIX /W:5 /R:5 /NP /LOG+:%usb%:\Robocopy\LOG_%short%.txt

Beendet den Job damit:

REN %usb%:\Robocopy\LOG_%short%.txt COMPLETE_LOG_%long%.log

COMPLETE_LOG_2018-06-27_10_53_54.log ist die am Ende erzeugte Datei und kann nach Dateinamen sortiert werden.

Chip Delozier
quelle
0

Jesses Antwort löste mein Problem mit dem Umbenennen von Dateien, indem das Leerzeichen im Stundenfeld entfernt wurde. So setze ich meine Variablen:

for /f "tokens=1,2,3,4 delims=/ " %%a in ("%date%") do set wday=%%a&set month=%%b&set day=%%c&set year=%%d
for /f "tokens=1,2 delims=:" %%a in ("%time: =0%") do set hour=%%a&set minute=%%b

Es funktioniert wie ein Champion. aus irgendeinem grund brauchte date nicht die gleiche behandlung, aber ich stelle mir vor, das liegt an den regionalen einstellungen.

bradzilla3k
quelle
0
    @echo off



    call :PAD aaa,2,0,grw
    echo [[aaa=%aaa%]]
    pause




rem #### Function PAD ####
    goto :PADEND
    :PAD <var>,<length>,<padchar>,<string>
        set padtot=%~2
        set padchar=%~3
        set padString=%~4
        :StartPADLOOP
            call :len lenpadString,%padString%
            if ["%lenpadString%"] GEQ ["%padtot%"] goto :EndPADLOOP
            set padString=%padchar%%padString%
            goto :StartPADLOOP
        :EndPADLOOP
        set %~1=%padString%
    GOTO :EOF
    :PADEND


rem #### Function LEN ####
    goto :LENEND
    :LEN <var>,<string>
        set LENtempvar=%~2
        rem echo {{S:%LENtempvar%}}
        set LENCOUNT=0    
        :startLENLOOP
            if ["%LENtempvar%"] EQU [""] goto :endLENLOOP
            rem echo {{A:%LENtempvar%}}
            set LENtempvar=%LENtempvar:~0,-1%
            rem echo {{B:%LENtempvar%}}
            set /a LENCOUNT=LENCOUNT+1
        goto :startLENLOOP
        :endLENLOOP
        set %~1=%LENCOUNT%
    GOTO :EOF
    :LENEND
Risoos
quelle
-2
set sFolderName=%time: =0%
xcopy "%UserProfile%\Pictures\*.jpg" Y:\"%DATE%-%sFolderName:~0,2%h%time:~3,2%m%time:~6,2%s-%random%" /I /C /Y

15.06.2015-03h43m34s-5357

5357-%random%"
Vitokhv
quelle
5
Obwohl der Code geschätzt wird, sollte er immer eine begleitende Erklärung haben. Das muss nicht lange dauern, wird aber erwartet.
Peterh sagt, Monica