在批处理作业中创建文件名作为时间戳

时间:2009-06-30 16:03:02

标签: windows batch-file cmd timestamp

我们有一个每天运行的批处理作业,并将文件复制到拾取文件夹。我还想获取该文件的副本并将其放入文件夹

的存档文件夹中
 yyyy-MM-dd.log

在Windows批处理作业中执行此操作的最简单方法是什么?

我基本上在寻找这个Unix命令的等价物:

cp source.log `date +%F`.log

17 个答案:

答案 0 :(得分:96)

CP source.log %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%.log

但它依赖于语言环境。我不确定%DATE%是否已本地化,或取决于Windows中为短日期指定的格式。

以下是一种与区域设置无关的方法,可以从this answer中提取当前日期,但这取决于WMICFOR /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

答案 1 :(得分:43)

这对我有用,是一个文件名安全的解决方案(虽然它生成了MM-dd-YYYY格式):

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

第一个命令需要DATE并用/替换-,取时间并用:替换-,并将它们组合成DATE @ TIME格式。第二个set语句会删除所有空格,第三个set会将,替换为.并附加.jpg扩展名。

以上代码用于从安全IP摄像机中提取图像以进行进一步处理的小脚本:

: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

答案 2 :(得分:15)

对于法语区域设置(仅限法国),请注意,因为/出现在日期中:

echo %DATE%
08/09/2013

对于我们的日志文件问题,以下是法语区域设置的建议:

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%

答案 3 :(得分:10)

这是一个独立于语言环境的解决方案(复制到名为SetDateTimeComponents.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%

我把所有.cmd脚本放到同一个文件夹中(%SCRIPTROOT%);任何需要日期/时间值的脚本都将调用SetDateTimeComponents.cmd,如下例所示:

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%

如示例所示,只要需要更新日期/时间值,就可以调用SetDateTimeComponents.cmd。隐藏时间解析脚本自己的SetDateTimeComponents.cmd文件是隐藏丑陋细节的好方法,更重要的是,避免拼写错误。

答案 4 :(得分:6)

这将确保输出为2位数值...您可以根据自己的喜好重新排列输出并通过取消注释诊断部分进行测试。享受!

(我从其他论坛借了很多这个......)

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

答案 5 :(得分:5)

我经常使用它,并将所有内容放入一个复制命令中。以下将example.txt复制为example_YYYYMMDD_HHMMSS.txt,当然您可以修改它以适合您的首选格式。只有在filespec中有任何空格时才需要引号。如果您想重复使用完全相同的日期/时间戳,则需要将其存储在变量中。

copy "{path}\example.txt" "{path}\_%date:~10,4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.txt"

答案 6 :(得分:3)

因为将%DATE%%TIME%撕开并将它们混合在一起的想法充其量只是看起来很脆弱,所以这里有一个使用powershell oneliner的替代方案:

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

get-date的引用是here,具有.NET样式和UNIX样式的格式选项。

答案 7 :(得分:2)

我把一个小C程序放在一起打印出当前时间戳(语言环境安全,没有坏字符......)。然后,我使用FOR命令将结果保存在环境变量中:

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

这是一个链接:

https://github.com/HarryPehkonen/dos-timestamp

答案 8 :(得分:2)

我知道这是一个老帖子,但有一个更简单的答案(尽管它可能只适用于较新版本的Windows)。只需使用DATE和TIME dos命令的/ t参数来显示日期或时间,而不是提示您设置它,如下所示:

@echo off
echo Starting test batch file > testlog.txt
date /t >> testlog.txt
time /t >> testlog.txt

答案 9 :(得分:2)

您可以简单地检测当前的本地格式,并以您的格式获取日期,例如:

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

答案 10 :(得分:2)

也许这会有所帮助:

echo off
@prompt set date=$d$_ set time=$t$h$h$h
echo some log >> %date% %time%.log
exit

echo off
set v=%date%.log
echo some log >> %v%

答案 11 :(得分:2)

使用当前日期作为文件名创建一个文件(例如,2008-11-08.dat)

echo hello > %date%.dat    

使用当前日期但没有“ - ”(例如20081108.dat)

echo hello > %date:-=%.dat   

答案 12 :(得分:1)

我知道这个帖子已经老了,但我只是想在这里添加它,因为它帮助我尝试将这一切都弄清楚了。关于这一点的好处是你可以将它放在一个循环中,以便批处理文件始终运行。服务器正常运行日志或其他东西。无论如何,这就是我用它的原因。我希望有一天能帮到某人。

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

答案 13 :(得分:1)

1)您可以下载GNU日期附带的GNU coreutils

2)您可以使用VBScript,这使得在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

将脚本运行为:

c:\test> cscript /nologo myscript.vbs

答案 14 :(得分:0)

这适用于(我的)德国语言环境,应该可以根据您的需要进行调整......

forfiles /p *PATH* /m *filepattern* /c "cmd /c ren @file 
%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%_@file"

答案 15 :(得分:0)

对于要部署的大型zip文件,我使用25分钟的时间。此页面上没有其他人以前提到过它,因此我将小脚本放在这里:

set /a "quarter_hours=%time:~0,2%*4 + %time:~3,2% / 15"
set "zip_file=release_%DATE:~-4%.%DATE:~4,2%.%DATE:~7,2%.%quarter_hours%.zip"

从午夜到凌晨5点,它还没有将四分之一小时设为零,但它仍然可以做到,因此您可以每天多次进行加盖印章,几乎不会发生碰撞。

希望有帮助。

答案 16 :(得分:0)

略微调整了马丁的建议,在文件名中添加了时间戳:

forfiles /p [foldername] /m rsync2.log /c "cmd /c ren @file %DATE:~6,4%%DATE:~3,2%%DATE:~0,2%_%time:~-11,2%-%time:~-8,2%-%time:~-5,2%-@file

对于10:17:21 23/10/2019结果是:

  

20191023_10-17-21-rsync2.log