web-dev-qa-db-fra.com

Besoin de zéro devant pour le script de traitement par lots à l'aide de la variable% time%

J'ai rencontré un bogue dans mon script DOS qui utilise des données de date et d'heure pour nommer les fichiers. Le problème était que je me suis retrouvé avec un écart parce que la variable de temps ne fournissait pas automatiquement le zéro initial pour l'heure <10. Donc, l'exécution> echo% time% donne: '9: 29: 17.88'.

Quelqu'un connaît-il un moyen de remplir conditionnellement les zéros de tête pour résoudre ce problème?

Plus d'informations: Ma commande de définition de nom de fichier est:

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

qui finit par être: C:\Temp\robolog_20100602_ 93208.log (pour 9h23 du matin).

Cette question est liée à celle-ci .

Merci

26
Ira

Un moyen très simple consiste à remplacer simplement l'espace de tête par zéro:
echo %TIME: =0%
les sorties:
09:18:53,45

60
Jesse

Ma solution était d'utiliser l'idée suivante:

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

Idée similaire à réponse de Dennis . Le problème est que la largeur de %time% est toujours le même, il insère donc un espace au début au lieu de renvoyer une chaîne plus courte.

Vous pouvez vous en débarrasser avec for:

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

Le reste est donc plus ou moins le même.

5
Joey

En utilisant la contribution de Jesse, je viens de créer une variable avec la sortie modifiée. Ensuite, je référence cette variable pour construire la partie heure.

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

Avec la source d'origine:

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

Merci Jesse. J'aurais voté si j'avais les points de réputation.

3
Ben Newcomb

Ce qui suit reprend quelques lignes mais est clair et compréhensible. Il enregistre stdout et stderr dans des fichiers séparés, chacun avec un horodatage. L'horodatage inclut l'année, le mois, le jour, l'heure, la minute et la seconde, dans cet ordre. Les horodatages doivent toujours avoir le composant de date le plus significatif en premier (année) et le composant le moins (secondes) en dernier. Cela permet aux listes de fichiers d'être dans l'ordre chronologique. Sans plus tarder, voici ma solution.

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

Pour la solution la plus compacte mettant en œuvre tout ce qui précède, je pense que

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

fonctionnerait ici sans ajouter de nouvelles lignes au script. C'est peut-être moins élégant que plusieurs solutions de commande, cependant ..

1
Jerry

Cela crée un horodatage triable et la deuxième ligne s'assure qu'il n'y a pas d'espace pour l'heure à un chiffre, etc., pour le rendre utilisable pour les scripts:

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

Production:

2018.02.26__9.47.34

0
Muposat

Cela met un zéro au début du temps et prend les deux derniers chiffres de l'heure (les minutes et les secondes positions de départ sont décalées d'une unité). Donc 3 heures du matin devient "03" puis "03" et l'heure 15 devient "015" puis "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

Moins lisible:

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

Une ligne de code fera ce dont vous avez besoin:

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

Par exemple, j'utilise% Date%, puis j'ajoute un zéro non significatif à une variable que j'utilise pour déterminer si je dois remplacer l'espace principal par un zéro pour% 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
Richard Wright

Merci de l'aide d'en haut ... Voici ce que j'utilise:

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

J'ai ensuite des journaux qui sont appelés dans des travaux Robocopy comme celui-ci:

Il y en a beaucoup comme ceci:

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

Termine le travail avec ceci:

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

COMPLETE_LOG_2018-06-27_10_53_54.log est le fichier produit à la fin et il est triable par nom de fichier.

0
Chip Delozier

La réponse de Jesse a résolu mon problème de changement de nom de fichier en éliminant l'espace dans le champ heure. Voici comment je règle mes variables:

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

Cela fonctionne comme un champion; pour une raison quelconque, la date n'a pas eu besoin du même traitement, mais j'imagine que cela dépend des paramètres régionaux.

0
bradzilla3k
    @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
0
Risoos