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

26

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

Ira
la source
Il est possible d'obtenir la valeur d'heure rembourrée ... FOR / F "TOKENS = 1 DELIMS =:" %% A IN ('TIME / T') DO SET HH = %% A puis remplacez% time: ~ 0,2% avec% HH%, j'espérais une solution plus compacte, mais cela fonctionnera.
Ira
Une solution "plus compacte" serait quelque chose dans un autre langage (powershell? Python? Perl? WSH?).
grawity
Commuté pour marquer la réponse de Jesse comme la solution que j'utilise. Il fonctionne à la fois avec des heures avant midi pour un pad avec 0 principal et aussi avec des heures militaires après midi.
Ira

Réponses:

60

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

Jesse
la source
1
Ça marche! c'est la solution la plus simple je pense ..
aerobrain
Cela peut-il également être fait avec plusieurs caractères? iE tous ',', '' et ':'. Actuellement, je crée des variables intermédiaires mais bien sûr, cela ne fonctionne qu'en raison du petit nombre de remplacements. Pour plus, ce serait lourd.
Devolus
1
J'utilise ceci dans une deuxième "étape" pour modifier les heures: set HH=%time:~-11,2% set MM=%time:~-8,2% set SS=%time:~-5,2% set ISOTIME=%HH: =0%-%MM%-%SS% echo %ISOTIME%Voir aussi ss64.com/nt/syntax-replace.html
gérer
+1 C'est la réponse la plus courte / la meilleure. Comment j'ai utilisé: set timestring=%TIME: =0%tôt dans le sous-appel - il suffit alors de travailler avec à la timestringplace (ou quelle que soit la variable que vous utilisez).
bshea
14

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

SET HOUR=%TIME:~0,2%
IF "%HOUR:~0,1%" == " " SET HOUR=0%HOUR:~1,1%
Neil Ratcliffe
la source
Je l'aime. Simple et intuitif.
Ken
Fonctionne sur les fenêtres modernes, mais donne une erreur de syntaxe sur le serveur 2003!
Dr BDO Adams
Fonctionne parfaitement sur 2008+, la solution la plus élégante. Merci.
bjoster
1
but gives syntax error on server 2003- pourquoi ça vous intéresse en 2016?
Marcin Orlowski
Parfait sur l'invite de commande Windows 10
Mike Upjohn
5

Idée similaire à la réponse de Dennis . Le problème est que la largeur de %time%est toujours la même, donc elle insère 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.

Joey
la source
2
Cette solution fonctionne pour> 10 mais crée maintenant '010' pour 10: ...
Devolus
3
La réponse de Jesse est la bonne ...
Simon Sobisch
C'est une très mauvaise réponse, elle tombe en panne dès qu'il y a deux chiffres dans l'heure. Je ne peux pas croire que l'OP l'a sélectionné.
thebunnyrules
3

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.

Ben Newcomb
la source
1

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 ..

Jerry
la source
1

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 comprend 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%
David
la source
0

Cela marque 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
En pause jusqu'à nouvel ordre.
la source
1
Je ne suis pas sûr que cela fonctionne. Si je lance 'set T = 0% time%' et qu'il est 9h38, l'écho% T% renvoie: '0 9: 38: 54.21', puis en prenant% T: ~ 1,2% obtient l'espace, sans interligne 0.
Ira
0

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%
Richard Wright
la source
0

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

Sortie:

2018.02.26__9.47.34

Muposat
la source
0

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.

Chip Delozier
la source
0

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.

bradzilla3k
la source
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
la source
-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
la source
5
Bien que le code soit apprécié, il doit toujours être accompagné d'une explication. Cela ne doit pas être long, mais c'est prévu.
peterh dit réintégrer Monica le