Precisa de zero à esquerda para script em lote usando a variável% time%

26

Me deparei com um bug no meu script DOS que usa dados de data e hora para nomear arquivos. O problema foi que eu acabei com uma lacuna porque a variável time não forneceu automaticamente zero inicial por hora <10. Portanto, executar> echo% time% retorna: '9: 29: 17,88'.

Alguém sabe uma maneira de preencher condicionalmente zeros à esquerda para corrigir isso?

Mais informações: Meu comando set filename é:

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

que acaba sendo: C: \ Temp \ robolog_20100602_ 93208.log (para 9:23 da manhã).

Esta questão está relacionada a esta .

obrigado

Ira
fonte
É possível obter o valor da hora acolchoada ... FOR / F "TOKENS = 1 DELIMS =:" %% A IN ('TIME / T') DEFINIR HH = %% A e substituir% time: ~ 0,2% com% HH%, eu esperava uma solução mais compacta, mas isso funcionaria.
Ira
Uma solução "mais compacta" seria algo em outra linguagem (powershell? Python? Perl? WSH?).
#
Mudou para marcar a resposta de Jesse como a solução que eu uso. Funciona com horário pré-meio-dia para preencher 0/0 e também com horário militar pós-meio-dia.
Ira

Respostas:

60

Uma maneira muito simples é simplesmente substituir o espaço inicial por zero:
echo %TIME: =0%
outputs:
09:18:53,45

Jesse
fonte
1
funciona! esta é a solução mais simples eu acho ..
aerobrain
Isso também pode ser feito com vários caracteres? Ou seja, todos ',', 'e': '. Atualmente, crio variáveis ​​intermediárias, mas é claro que isso funciona apenas devido ao pequeno número de substituições. Para mais, seria complicado.
Devolus 9/01/16
1
Estou usando isso em um segundo "passo" para modificar o Horário: set HH=%time:~-11,2% set MM=%time:~-8,2% set SS=%time:~-5,2% set ISOTIME=%HH: =0%-%MM%-%SS% echo %ISOTIME%Veja também ss64.com/nt/syntax-replace.html
manipule
+1 Esta é a resposta mais curta / melhor. Como eu usei: set timestring=%TIME: =0%no início da sub-chamada - então apenas trabalhe com timestring(ou qualquer variável que você use).
bshea
14

Minha solução foi usar a seguinte ideia:

SET HOUR=%TIME:~0,2%
IF "%HOUR:~0,1%" == " " SET HOUR=0%HOUR:~1,1%
Neil Ratcliffe
fonte
Eu gosto disso. Simples e intuitivo.
12774 Ken
Funciona em janelas modernas, mas fornece erro de sintaxe no servidor 2003!
Dr BDO Adams
Funciona perfeitamente na solução 2008+, mais elegante. Obrigado.
bjoster
1
but gives syntax error on server 2003- por que você se importa com isso em 2016?
Marcin Orlowski 24/01
Perfeito no prompt de comando do Windows 10
Mike Upjohn
5

Idéia semelhante à resposta de Dennis . O problema é que a largura de %time%é sempre a mesma, portanto, ele insere um espaço no início, em vez de retornar uma string mais curta.

Você pode se livrar disso com for:

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

O resto é mais ou menos o mesmo, então.

Joey
fonte
2
Esta solução funciona para> 10 mas agora cria '010' para 10: ...
Devolus
3
A resposta de Jesse é a correta ...
Simon Sobisch 14/07/16
Essa é uma resposta muito ruim, pois é quebrada assim que houver dois dígitos na hora. Não consigo acreditar que o OP o selecionou.
thebunnyrules
3

Usando a contribuição de Jesse, acabei de criar uma variável com a saída modificada. Então eu faço referência a essa variável para criar a parte da hora.

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

Com a fonte original:

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

Obrigado Jesse. Eu teria votado se tivesse os pontos de reputação.

Ben Newcomb
fonte
1

Para a solução mais compacta implementando tudo acima, acho que

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

funcionaria aqui sem adicionar novas linhas ao script. Talvez seja menos elegante que várias soluções de comando ..

Jerry
fonte
1

A seguir, são necessárias mais algumas linhas, mas é claro e compreensível. Ele salva stdout e stderr para separar arquivos, cada um com um carimbo de data / hora. O registro de data e hora inclui ano, mês, dia, hora, minuto e segundo, nessa ordem. Os carimbos de data / hora devem sempre ter o componente de data mais significativo primeiro (ano) e o menor componente (segundos) por último. Isso permite que as listagens de arquivos estejam na ordem do tempo. Sem mais delongas, aqui está a minha solução.

: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
fonte
0

Isso marca um zero no início do tempo e leva os últimos dois dígitos da hora (as posições de minuto e segundo iniciais são alteradas em um). Então, as 3 da manhã se tornam "03", depois "03" e a hora 15 se torna "015" e "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

Menos legível:

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
Pausado até novo aviso.
fonte
1
Não tenho certeza se isso funciona. Se eu executar 'set T = 0% time%' e forem 9h38, o eco% T% retornará: '0 9: 38: 54.21' e, depois,% T: ~ 1,2% obterá o espaço, sem avanço 0.
Ira
0

Uma linha de código fará o que você precisa:

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

Por exemplo, eu uso% Date% e adiciono um zero inicial a uma variável que utilizo para determinar se preciso substituir o espaço inicial por um zero para% 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%
Richard Wright
fonte
0

Isso cria um carimbo de data / hora classificável e a segunda linha garante que não haja espaços para a hora de um dígito, etc., para torná-lo utilizável para scripts:

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

Saída:

2018.02.26__9.47.34

Muposat
fonte
0

Obrigado por ajudar de cima ... É isso que estou 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

Em seguida, tenho logs chamados em trabalhos de Robocopy como este:

Existem muitos como este:

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 o trabalho com isso:

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

COMPLETE_LOG_2018-06-27_10_53_54.log é o arquivo produzido no final e pode ser classificado por nome de arquivo.

Chip Delozier
fonte
0

A resposta de Jesse resolveu meu problema de renomeação de arquivos, eliminando o espaço no campo hora. É assim que eu defino minhas variáveis:

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

Funciona como um campeão; por algum motivo, a data não precisou do mesmo tratamento, mas imagino que isso se deva às configurações regionais.

bradzilla3k
fonte
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
fonte
-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
fonte
5
Embora o código seja apreciado, ele deve sempre ter uma explicação que o acompanha. Isso não precisa ser longo, mas é esperado.
peterh diz restabelecer Monica