È necessario lo zero iniziale per lo script batch utilizzando la variabile% time%


26

Mi sono imbattuto in un bug nel mio script DOS che utilizza i dati di data e ora per la denominazione dei file. Il problema era che avevo un gap perché la variabile time non forniva automaticamente zero iniziale per ora <10. Quindi in esecuzione> echo% time% restituisce: '9: 29: 17.88'.

Qualcuno sa un modo per riempire condizionalmente gli zeri iniziali per risolvere questo problema?

Ulteriori informazioni: Il mio comando set nome file è:

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

che finisce per essere: C: \ Temp \ robolog_20100602_ 93208.log (per le 9:23 del mattino).

Questa domanda è collegata a questa .

Grazie


È possibile ottenere il valore dell'ora di riempimento ... FOR / F "TOKENS = 1 DELIMS =:" %% A IN ('TIME / T') DO SET HH = %% A quindi sostituire% time: ~ 0,2% con% HH% speravo in una soluzione più compatta, ma funzionerà.
Ira,

Una soluzione "più compatta" sarebbe qualcosa in un'altra lingua (powershell? Python? Perl? WSH?).
Grawity

Passato a contrassegnare la risposta di Jesse come la soluzione che uso. Funziona con entrambi i tempi di mezzogiorno per riempire con 0 leader e anche il tempo militare post-mezzogiorno.
Ira,

Risposte:


60

Un modo molto semplice è semplicemente sostituire lo spazio iniziale con zero:
echo %TIME: =0%
output:
09:18:53,45


1
Funziona! questa è la soluzione più semplice che penso ..
aerobrain

Questo può essere fatto anche con più personaggi? cioè tutti ',', '' e ':'. Attualmente creo variabili intermedie, ma ovviamente funziona solo per il numero limitato di sostituzioni. Per di più sarebbe ingombrante.
Devolus

1
Sto usando questo in un secondo "step" per modificare gli orari: set HH=%time:~-11,2% set MM=%time:~-8,2% set SS=%time:~-5,2% set ISOTIME=%HH: =0%-%MM%-%SS% echo %ISOTIME%vedi anche ss64.com/nt/syntax-replace.html
maniglia

+1 Questa è la risposta più breve / migliore. Come ho usato: set timestring=%TIME: =0%nelle prime chiamate secondarie, quindi lavora con timestringinvece (o con qualunque variabile tu usi).
bshea,

14

La mia soluzione era usare la seguente idea:

SET HOUR=%TIME:~0,2%
IF "%HOUR:~0,1%" == " " SET HOUR=0%HOUR:~1,1%

Mi piace. Semplice ed intuitivo
Ken,

Funziona su Windows moderno, ma fornisce un errore di sintassi sul server 2003!
Dr BDO Adams,

Funziona perfettamente su 2008+, la soluzione più elegante. Grazie.
Bjoster,

1
but gives syntax error on server 2003- perché te ne importa nel 2016?
Marcin Orlowski,

Perfetto sul prompt dei comandi di Windows 10
Mike Upjohn,

5

Un'idea simile alla risposta di Dennis . Il problema è che la larghezza di %time%è sempre la stessa, quindi inserisce uno spazio all'inizio invece di restituire una stringa più corta.

Puoi liberartene con for:

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

Il resto è più o meno lo stesso, quindi.


2
Questa soluzione funziona per> 10 ma ora crea '010' per 10: ...
Devolus

3
La risposta di Jesse è quella corretta ...
Simon Sobisch,

Questa è una pessima risposta, si interrompe non appena ci sono due cifre nell'ora. Non posso credere che l'OP lo abbia selezionato.
thebunnyrules,

3

Usando il contributo di Jesse, ho appena creato una variabile con l'output modificato. Quindi faccio riferimento a quella variabile per costruire la porzione di ora.

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

Con la fonte originale:

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

Grazie Jesse. Avrei votato se avessi avuto i punti reputazione.


1

Per la soluzione più compatta che implementa tutto quanto sopra, penso che

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

funzionerebbe qui senza aggiungere nuove righe allo script. È forse meno elegante di più soluzioni di comando, però ...


1

Quanto segue prende alcune righe in più ma è chiaro e comprensibile. Salva stdout e stderr in file separati, ognuno con un timestamp. Il timestamp include anno, mese, giorno, ora, minuti e secondi, in quell'ordine. I timestamp devono sempre avere la componente data più significativa per prima (anno) e l'ultima componente (secondi) per ultima. Ciò consente agli elenchi di file di essere in ordine temporale. Senza ulteriori indugi, ecco la mia soluzione.

: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%

0

Questo inserisce uno zero all'inizio dell'ora e prende le ultime due cifre dell'ora (le posizioni di inizio dei minuti e dei secondi sono spostate di una). Quindi 3 AM diventa "03" quindi "03" e l'ora 15 diventa "015" quindi "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

Meno facilmente:

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

1
Non sono sicuro che funzioni. Se eseguo 'set T = 0% time%' ed è 9:38, l'eco% T% restituisce: '0 9: 38: 54.21', quindi prendendo% T: ~ 1,2% ottiene lo spazio, nessun vantaggio 0.
Ira,

0

Una riga di codice farà ciò di cui hai bisogno:

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

Ad esempio, utilizzo% Date% e quindi aggiungo uno zero iniziale a una variabile che utilizzo per determinare se devo sostituire lo spazio iniziale con uno zero per% Time%.

    ::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%

0

Questo crea un timestamp ordinabile e la seconda riga assicura che non ci siano spazi per l'ora a una cifra, ecc., Per renderlo utilizzabile per gli script:

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

Produzione:

2018.02.26__9.47.34


0

Grazie per l'aiuto dall'alto ... Questo è quello che sto usando:

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

Ho quindi dei registri che vengono richiamati nei lavori Robocopy in questo modo:

Ce ne sono molti come questo:

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

Termina il lavoro con questo:

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

COMPLETE_LOG_2018-06-27_10_53_54.log è il file prodotto alla fine ed è ordinabile per nome file.


0

La risposta di Jesse ha risolto il mio problema di ridenominazione del file eliminando lo spazio nel campo dell'ora. Ecco come imposto le mie variabili:

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

Funziona come un campione; per qualche ragione la data non ha avuto bisogno dello stesso trattamento, ma immagino che dipenda dalle impostazioni regionali.


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

-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%"

5
Sebbene il codice sia apprezzato, dovrebbe sempre avere una spiegazione di accompagnamento. Questo non deve essere lungo ma è previsto.
Peter dice di reintegrare Monica il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.