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


90

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

 yyyy-MM-dd.log

Windows批处理作业中最简单的方法是什么?

我基本上正在寻找与Unix命令等效的命令:

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

在Windows .bat文件中获取所需格式的日期字符串时,看起来与建议的解决方案一样糟糕。老实说,只需检查机器上可用的编程语言(例如java,ruby,perl或其他),然后制作5秒钟的可执行文件即可获得所需的内容。我不会浪费任何时间维护.bat文件,该文件返回多行代码以获取具有正确格式的日期。
99索诺,2016年

Answers:


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

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

这是从此答案中提取当前日期的与语言环境无关的方法,但这取决于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

6
需要稍微摆弄索引,但这似乎可以解决问题。(尽管不能完全确定我理解减号逻辑)%DATE:〜-4%-%DATE:〜-7,-5%-%DATE:〜-10,-8%.log
Eoin Campbell

1
如果您想使用所有正指数,则可以使用:%DATE:
〜10,4

(我只是从很久以前的其他工作中得到的,我不知道为什么要像原来那样做,嘿。)
opello

3
这确实在其他区域设置上中断了。在我的情况下,命令返回2014-5.-01(原为2014-05-26)。因此,如果发布包含此内容的脚本,请非常小心!
amenthes 2014年

5
使用此时间(删除毫秒):%time:~-11,2%-%time:~-8,2%-%time:~-5,2%
MRC

48

这对我有用,并且是一个文件名安全的解决方案(尽管它生成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并替换/-,采用TIME并替换:-,然后将它们组合为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

我的控制台上的输出在10-12-2014@14-22-59,44.jpg毫秒前用逗号表示
BeNdErR 2014年

1
尝试set SAVESTAMP=%SAVESTAMP:,=.%.jpgecho语句之前添加。如果可行,我将更新答案。
Daniel Sokolowski

1
这不是与语言环境无关的。08.06.2016@15-42-20,33.jpg在我的德语笔记本电脑和Wed06-08-2016@15-43-45.89.jpg英语笔记本电脑上返回。
Hannobo

5
但是它仍然既不是语言环境独立的语言,也不是创建正确格式(iso8601)的格式yyyy-MM-dd
jeb

1
令人烦恼的是,第一行仍然声称它是独立于区域设置的,只是看到它不是在尝试之后……
m3tikn0b

16

仅对于法语语言环境(法国),请小心,因为它会/出现在日期中:

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%

优秀的!读取起来有些困难,但是确实可以按照您想要的格式格式化输出。
davitof 2014年

2
很好,但是要避免使用白色字符,请小心,因为HOUR可以这样渲染1位数:("_0:00"下划线字符是一个空格)
daVe

1
我得到“ log- / 18 /。0.Sa- 9.16.txt”的答案。
ledlogic

@ledlogic:您的语言环境是什么?此答案适用于法国语言环境。
奥宾

1
无法正常工作,我在Windows 7上获得此信息-log- / 05 /。0.We-18.13.tx
Sam B

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文件中是一种隐藏丑陋细节的好方法,更重要的是避免输入错误。


2
抱歉,这不是与语言环境无关的:在我的法语Windows上,我收到“ 18 -2014- @ 13:14:43”
davitof 2014年

1
可以确认:不依赖于语言环境。prompt $d $t在我的系统上返回30.05.2016 15:35:56,93
Hannobo

7

由于撕裂的想法%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在这里,有两个.NET的风格和UNIX风格的格式选项。


6

我经常使用它,并将所有内容放入一个复制命令中。以下内容将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

这将确保输出为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%

2

创建一个以当前日期为文件名的文件(例如2008-11-08.dat)

echo hello > %date%.dat    

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

echo hello > %date:-=%.dat   

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%

不错的一只Secko ...%date%的值似乎正满足我的需求。您有机会解释一下SET语句。什么是$ d $ set和$ t $ h $ h $ h
Eoin Campbell,2009年

1
set是“ SET变量”语句。日期变量为$ d $ _(日期+其余时间),时间变量为$ t $ h $ h $ h(时间+毫秒)。我试图展示如何使用一组变量来完成它,而无需提示行就可以正常工作。我基本上尝试过将日期设置为%YYYY %% MM %% DD%,但是我在这里运行Linux并在SciTE上编译脚本,所以我不知道它是否有效。对不起,如果它不起作用。
塞科

忘记添加,$ _是换行符。
塞科

1
也可以尝试@prompt // $ d $ _ $ t $ h $ h $ h $ h $ h $ h $ h //
Secko 2009年

请注意,这也不与语言环境无关。日期被格式化为当前的区域性设置,例如DD.MM.YYYY(德语)。
Hannobo

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


2

我知道这个线程很旧,但是我只想在这里添加它,因为它帮助我尝试了很多事情并弄清楚了它。这样做的好处是,您可以将其循环放入始终运行的批处理文件。服务器正常运行时间日志或其他内容。那就是我一直使用它的原因。我希望有一天能对某人有所帮助。

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

这对我很有用,尽管在“ .cmd”文件中,“ FreshTime”变量中的冒号在“ robocopy” cmdline中用作文件名时引起错误: ERROR : Invalid Parameter #12 : "/LOG:C:\opt\Sync_08.10.2020_16:27:39.log"作为修复,我改用了破折号:set FreshTime=%hour%-%min%-%secs%
netdesignate

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

2

我知道这是一篇旧文章,但是有一个FAR较简单的答案(尽管可能仅在更新版本的Windows中有效)。只需对DATE和TIME dos命令使用/ t参数,仅显示日期或时间,而不提示您进行设置,如下所示:

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

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

0

这在(我的)德国语言环境下效果很好,应该可以根据您的需要进行调整...

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

%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%也适用于葡萄牙地区!我的意思是YYYYMMDD
费尔南多·法布雷蒂

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点,它还没有将四分之一小时调零,但它仍然可以做到,因此您可以每天多次加盖印章,几乎不会发生碰撞。

希望能有所帮助。


0

略微调整了Martin的建议,将时间戳添加到了文件名:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.