代码之家  ›  专栏  ›  技术社区  ›  Eoin Campbell

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

  •  76
  • Eoin Campbell  · 技术社区  · 16 年前

     yyyy-MM-dd.log
    

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

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

    cp source.log `date +%F`.log
    
    15 回复  |  直到 9 年前
        1
  •  109
  •   Community CDub    8 年前
    CP source.log %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%.log
    

    %DATE% 是本地化的,或取决于Windows中为短日期指定的格式。

    下面是一种独立于区域设置的方法,可以从中提取当前日期 this answer ,但这取决于 WMIC 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
    
        2
  •  50
  •   elixenide Ren    7 年前

    这对我来说很有效,是一个文件名安全的解决方案(尽管它会生成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
    

    第一个命令获取日期并替换 / 具有 - : 具有 - 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
    
        3
  •  18
  •   Aubin    8 年前

    对于 仅限法国地区(法国) / 出现在日期中:

    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%
    
        4
  •  10
  •   totorocat    16 年前

    这是一个独立于区域设置的解决方案(复制到名为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文件中是隐藏难看细节的好方法,更重要的是,避免输入错误。

        5
  •  10
  •   tboz203    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 here

        6
  •  7
  •   Mogsdad    9 年前

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

    这将确保输出为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%
    
        8
  •  2
  •   RealHowTo    16 年前

    echo hello > %date%.dat    
    

    带当前日期但不带“-”(例如20081108.dat)

    echo hello > %date:-=%.dat   
    
        9
  •  2
  •   Secko    16 年前

    也许这会有帮助:

    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%
    
        10
  •  2
  •   Harry Pehkonen    11 年前

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

        11
  •  2
  •   Haxslie    9 年前

    我知道这条线很旧,但我只想在这里加上这条线,因为它帮了我很多努力,让我弄清楚这一切,而且它很干净。这样做的好处是,您可以将它放在一个始终运行的批处理文件的循环中。服务器启动时间日志之类的。这就是我用它的目的。我希望有一天这能帮助别人。

    @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%
    
        12
  •  2
  •   Peter Mortensen icecrime    8 年前

    ::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
    
        13
  •  2
  •   Dean    7 年前

    我知道这是一篇老文章,但有一个简单得多的答案(尽管它可能只适用于较新版本的windows)。只需在日期和时间dos命令中使用/t参数,即可仅显示日期或时间,而不提示您进行设置,如下所示:

    @echo off
    echo Starting test batch file > testlog.txt
    date /t >> testlog.txt
    time /t >> testlog.txt
    
        14
  •  1
  •   Peter Mortensen icecrime    12 年前

    1) 你可以下载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
    
        15
  •  0
  •   Martin    7 年前

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

    对于用于部署的大型zip文件,我使用四分之一小时。在此页面上没有其他人提到过,因此我将把我的小脚本放在这里:

    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点这一刻钟还没有归零,但它仍然做到了这一点,这样你就可以一天多次在几乎没有碰撞的情况下进行盖章释放。

        17
  •  0
  •   Gennady Sorochan    5 年前

    使用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
    

    对于2019年10月23日10:17:21,结果是:

    20191023_10-17-21-rsync2.log

        18
  •  0
  •   user17032068    3 年前
                echo Date and Time: %date% %time%
                rem 29/09/2021 10:01:34,23
    
                set timestamp=%time: =0%
                set timestamp=%timestamp::=%
                set timestamp=%timestamp:,=%
                set timestamp=%date:/=%%timestamp%
    
                echo Timestamp (ddMMYYYYHHmmssms): %timestamp%
                rem 2909202109543118
    
                set timestamp=%timestamp:~4,4%%timestamp:~2,2%%timestamp:~0,2%%timestamp:~8,8%
                echo Timestamp (YYYYMMddHHmmssms) %timestamp%
                rem 2021092910013423