我们有一个每天运行的批处理作业,并将文件复制到取件文件夹。我还想复制该文件并将其放入文件名的存档文件夹中
yyyy-MM-dd.log
Windows批处理作业中最简单的方法是什么?
我基本上正在寻找与Unix命令等效的命令:
cp source.log `date +%F`.log
我们有一个每天运行的批处理作业,并将文件复制到取件文件夹。我还想复制该文件并将其放入文件名的存档文件夹中
yyyy-MM-dd.log
Windows批处理作业中最简单的方法是什么?
我基本上正在寻找与Unix命令等效的命令:
cp source.log `date +%F`.log
Answers:
CP source.log %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%.log
但这取决于语言环境。我不确定是否%DATE%
已本地化,或取决于Windows中为短日期指定的格式。
这是从此答案中提取当前日期的与语言环境无关的方法,但这取决于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
2014-5.-01
(原为2014-05-26
)。因此,如果发布包含此内容的脚本,请非常小心!
%time:~-11,2%-%time:~-8,2%-%time:~-5,2%
这对我有用,并且是一个文件名安全的解决方案(尽管它生成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
毫秒前用逗号表示
set SAVESTAMP=%SAVESTAMP:,=.%.jpg
在echo
语句之前添加。如果可行,我将更新答案。
08.06.2016@15-42-20,33.jpg
在我的德语笔记本电脑和Wed06-08-2016@15-43-45.89.jpg
英语笔记本电脑上返回。
yyyy-MM-dd
仅对于法语语言环境(法国),请小心,因为它会/
出现在日期中:
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%
"_0:00"
下划线字符是一个空格)
这是独立于语言环境的解决方案(复制到名为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文件中是一种隐藏丑陋细节的好方法,更重要的是避免输入错误。
prompt $d $t
在我的系统上返回30.05.2016 15:35:56,93
这将确保输出为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%
也许这可以帮助:
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%
我整理了一些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"
这里是一个链接:
我知道这个线程很旧,但是我只想在这里添加它,因为它帮助我尝试了很多事情并弄清楚了它。这样做的好处是,您可以将其循环放入始终运行的批处理文件。服务器正常运行时间日志或其他内容。那就是我一直使用它的原因。我希望有一天能对某人有所帮助。
@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%
ERROR : Invalid Parameter #12 : "/LOG:C:\opt\Sync_08.10.2020_16:27:39.log"
作为修复,我改用了破折号:set FreshTime=%hour%-%min%-%secs%
您可以简单地检测当前的本地格式并以您的格式获取日期,例如:
::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
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
略微调整了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