Création d'un nom de fichier comme horodatage dans un travail par lots
nous avons un travail par lot qui s'exécute tous les jours et copie un fichier dans un dossier de collecte. Je veux aussi prendre une copie de ce fichier et le déposer dans un dossier d'archives avec le nom de fichier
yyyy-MM-dd.log
Quelle est la meilleure façon de faire cela dans un travail Windows batch?
je suis à la recherche d'un équivalent de cette commande Unix:
cp source.log `date +%F`.log
15 réponses
CP source.log %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%.log
mais ça dépend de la localisation. Je ne suis pas sûr si %DATE%
est localisé, ou dépend du format spécifié pour la date courte dans Windows.
Voici une façon locale-indépendante pour extraire la date actuelle de cette réponse , mais elle dépend de WMIC
et FOR /F
:
FOR /F %%A IN ('WMIC OS GET LocalDateTime ^| FINDSTR \.') DO @SET B=%%A
CP source.log %B:~0,4%-%B:~4,2%-%B:~6,2%.log
cela a fonctionné pour moi et était une solution sans nom de fichier (bien qu'il génère un format MM-JJ-AAAA):
C:\ set SAVESTAMP=%DATE:/=-%@%TIME::=-%
C:\ set SAVESTAMP=%SAVESTAMP: =%
C:\ set SAVESTAMP=%SAVESTAMP:,=.%.jpg
C:\ echo %SAVESTAMP%
11-04-2012@20-52-42.79.jpg
la première commande prend une DATE et remplace /
par -
, prend le temps et remplace :
par -
, et les combine dans le format DATE@TIME. Le deuxième énoncé set
supprime tous les espaces et le troisième set
remplace ,
par .
et ajoute le .jpg
extension.
le code ci-dessus est utilisé dans un petit script qui tire des images d'une caméra IP de sécurité pour un traitement ultérieur:
:while
set SAVESTAMP=%DATE:/=-%@%TIME::=-%
set SAVESTAMP=%SAVESTAMP: =%
set SAVESTAMP=%SAVESTAMP:,=.%.jpg
wget-1.10.2.exe --tries=0 -O %SAVESTAMP% http://admin:<password>@<ip address>:<port>/snapshot.cgi
timeout 1
GOTO while
Pour paramètres Régionaux français (France) SEULEMENT , être prudent, car /
apparaît dans la date :
echo %DATE%
08/09/2013
pour notre problème de fichier journal, voici ma proposition pour Locale FRANÇAISE seulement :
SETLOCAL
set LOGFILE_DATE=%DATE:~6,4%.%DATE:~3,2%.%DATE:~0,2%
set LOGFILE_TIME=%TIME:~0,2%.%TIME:~3,2%
set LOGFILE=log-%LOGFILE_DATE%-%LOGFILE_TIME%.txt
rem log-2014.05.19-22.18.txt
command > %LOGFILE%
Voici une solution locale indépendante (copier dans un fichier nommé Setdatetimecomposants.cmd):
@echo off
REM This script taken from the following URL:
REM http://www.winnetmag.com/windowsscripting/article/articleid/9177/windowsscripting_9177.html
REM Create the date and time elements.
for /f "tokens=1-7 delims=:/-, " %%i in ('echo exit^|cmd /q /k"prompt $d $t"') do (
for /f "tokens=2-4 delims=/-,() skip=1" %%a in ('echo.^|date') do (
set dow=%%i
set %%a=%%j
set %%b=%%k
set %%c=%%l
set hh=%%m
set min=%%n
set ss=%%o
)
)
REM Let's see the result.
echo %dow% %yy%-%mm%-%dd% @ %hh%:%min%:%ss%
j'ai mis tout mon .les scripts cmd dans le même dossier (%SCRIPTROOT%); tout script qui a besoin de valeurs date/heure appellera SetDateTimeComponents.cmd comme dans l'exemple suivant:
setlocal
@echo Initializing...
set SCRIPTROOT=%~dp0
set ERRLOG=C:\Oopsies.err
:: Log start time
call "%SCRIPTROOT%\SetDateTimeComponents.cmd" >nul
@echo === %dow% %yy%-%mm%-%dd% @ %hh%:%min%:%ss% : Start === >> %ERRLOG%
:: Perform some long running action and log errors to ERRLOG.
:: Log end time
call "%SCRIPTROOT%\SetDateTimeComponents.cmd" >nul
@echo === %dow% %yy%-%mm%-%dd% @ %hh%:%min%:%ss% : End === >> %ERRLOG%
comme le montre l'exemple, vous pouvez appeler SetDateTimeComponents.cmd chaque fois que vous avez besoin de mettre à jour les valeurs date/heure. Cacher le script d'analyse du temps c'est son propre Setdatetimcomposants.cmd fichier est une bonne façon de cacher les détails laids, et, plus important encore, éviter les fautes de frappe.
cela permettra de s'assurer que la sortie est une valeur à deux chiffres...vous pouvez réarranger la sortie à votre goût et tester en dés-commentant la section diagnostics. Profitez-en!
(j'ai emprunté beaucoup d'autres forums...)
:: ------------------ Date and Time Modifier ------------------------
@echo off
setlocal
:: THIS CODE WILL DISPLAY A 2-DIGIT TIMESTAMP FOR USE IN APPENDING FILENAMES
:: CREATE VARIABLE %TIMESTAMP%
for /f "tokens=1-8 delims=.:/-, " %%i in ('echo exit^|cmd /q /k"prompt $D $T"') do (
for /f "tokens=2-4 skip=1 delims=/-,()" %%a in ('echo.^|date') do (
set dow=%%i
set %%a=%%j
set %%b=%%k
set %%c=%%l
set hh=%%m
set min=%%n
set sec=%%o
set hsec=%%p
)
)
:: ensure that hour is always 2 digits
if %hh%==0 set hh=00
if %hh%==1 set hh=01
if %hh%==2 set hh=02
if %hh%==3 set hh=03
if %hh%==4 set hh=04
if %hh%==5 set hh=05
if %hh%==6 set hh=06
if %hh%==7 set hh=07
if %hh%==8 set hh=08
if %hh%==9 set hh=09
:: --------- TIME STAMP DIAGNOSTICS -------------------------
:: Un-comment these lines to test output
:: echo dayOfWeek = %dow%
:: echo year = %yy%
:: echo month = %mm%
:: echo day = %dd%
:: echo hour = %hh%
:: echo minute = %min%
:: echo second = %sec%
:: echo hundredthsSecond = %hsec%
:: echo.
:: echo Hello!
:: echo Today is %dow%, %mm%/%dd%.
:: echo.
:: echo.
:: echo.
:: echo.
:: pause
:: --------- END TIME STAMP DIAGNOSTICS ----------------------
:: assign timeStamp:
:: Add the date and time parameters as necessary - " yy-mm-dd-dow-min-sec-hsec "
endlocal & set timeStamp=%yy%%mm%%dd%_%hh%-%min%-%sec%
echo %timeStamp%
Je l'utilise fréquemment, et je mets tout dans une commande de copie unique. Les exemplaires suivants exemple.txt as example_yyymmdd_hhmmss.txt et bien sûr vous pouvez le modifier pour convenir à votre format préféré. Les guillemets ne sont nécessaires que s'il y a des espaces dans le filespec. Si vous souhaitez réutiliser exactement le même horodatage, vous auriez besoin de le stocker dans une variable.
copy "{path}\example.txt" "{path}\_%date:~10,4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.txt"
créer un fichier avec la date courante comme nom de fichier (ex. 2008-11-08.dat)
echo hello > %date%.dat
avec la date courante mais sans le " - " (ex. 20081108.dat)
echo hello > %date:-=%.dat
peut-être que cela peut aider:
echo off
@prompt set date=$d$_ set time=$t$h$h$h
echo some log >> %date% %time%.log
exit
ou
echo off
set v=%date%.log
echo some log >> %v%
j'ai mis en place un petit programme C pour imprimer l'horodatage actuel (locale-safe, no bad characters...). Ensuite, j'utilise la commande FOR pour sauvegarder le résultat dans une variable d'environnement:
:: Get the timestamp
for /f %%x in ('@timestamp') do set TIMESTAMP=%%x
:: Use it to generate a filename
for /r %%x in (.\processed\*) do move "%%~x" ".\archived\%%~nx-%TIMESTAMP%%%~xx"
voici un lien:
vous pouvez simplement détecter le format local actuel et obtenir la date dans votre format, par exemple:
::for 30.10.2016 dd.MM.yyyy
if %date:~2,1%==. set d=%date:~-4%%date:~3,2%%date:~,2%
::for 10/30/2016 MM/dd/yyyy
if %date:~2,1%==/ set d=%date:~-4%%date:~,2%%date:~3,2%
::for 2016-10-30 yyyy-MM-dd
if %date:~4,1%==- set d=%date:~,4%%date:~5,2%%date:~-2%
::variable %d% have now value: 2016103 (yyyyMMdd)
set t=%time::=%
set t=%t:,=%
::variable %t% have now time without delimiters
cp source.log %d%_%t%.log
je sais que c'est un vieux post, mais il y a une réponse beaucoup plus simple (bien que peut-être il ne fonctionne que dans les nouvelles versions de windows). Il suffit d'utiliser le paramètre /t pour les commandes dos DATE et TIME pour n'afficher que la date ou l'heure et ne pas vous inviter à la définir, comme ceci:
@echo off
echo Starting test batch file > testlog.txt
date /t >> testlog.txt
time /t >> testlog.txt
parce que l'idée de déchirer %DATE%
et %TIME%
et de les séparer et de les remuer ensemble semble au mieux fragile, voici une alternative qui utilise un oneliner powershell:
for /f %i in ('powershell -c "get-date -format yyyy-MM-dd--HH-mm-ss"') do @set DATETIME=%i
set LOGFILE=my-script-%DATETIME%.txt
Référence get-date
est ici , avec des options de format pour les deux .NET-de style et de style UNIX.
1) vous pouvez télécharger GNU coreutils qui vient avec GNU date
2) Vous pouvez utiliser VBScript , ce qui rend la manipulation de date plus facile dans Windows:
Set objFS = CreateObject("Scripting.FileSystemObject")
strFolder = "c:\test"
Set objFolder = objFS.GetFolder(strFolder)
current = Now
mth = Month(current)
d = Day(current)
yr = Year(current)
If Len(mth) <2 Then
mth="0"&mth
End If
If Len(d) < 2 Then
d = "0"&d
End If
timestamp=yr & "-" & mth &"-"& d
For Each strFile In objFolder.Files
strFileName = strFile.Name
If InStr(strFileName,"file_name_here") > 0 Then
BaseName = objFS.GetBaseName(strFileName)
Extension = objFS.GetExtensionName(strFileName)
NewName = BaseName & "-" & timestamp & "." & Extension
strFile.Name = NewName
End If
Next
exécutez le script comme:
c:\test> cscript /nologo myscript.vbs
je sais que ce fil est vieux mais je veux juste ajouter ceci ici parce qu'il m'a beaucoup aidé à essayer de comprendre tout cela et son propre. La chose agréable à ce sujet est que vous pouvez le mettre dans une boucle pour un fichier batch qui est toujours en cours d'exécution. Serveur de temps de journal ou quelque chose. C'est ce que je l'utilise pour de toute façon. J'espère que cela aide quelqu'un un jour.
@setlocal enableextensions enabledelayedexpansion
@echo off
call :timestamp freshtime freshdate
echo %freshdate% - %freshtime% - Some data >> "%freshdate - Somelog.log"
:timestamp
set hour=%time:~0,2%
if "%hour:~0,1%" == " " set hour=0%hour:~1,1%
set min=%time:~3,2%
if "%min:~0,1%" == " " set min=0%min:~1,1%
set secs=%time:~6,2%
if "%secs:~0,1%" == " " set secs=0%secs:~1,1%
set FreshTime=%hour%:%min%:%secs%
set year=%date:~-4%
set month=%date:~4,2%
if "%month:~0,1%" == " " set month=0%month:~1,1%
set day=%date:~7,2%
if "%day:~0,1%" == " " set day=0%day:~1,1%
set FreshDate=%month%.%day%.%year%
cela fonctionne bien avec (mon) local allemand, devrait être possible de l'ajuster à vos besoins...
forfiles /p *PATH* /m *filepattern* /c "cmd /c ren @file
%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%_@file"