我需要备份带有日期时间戳的现有文件夹,并将其替换(删除并重新创建)为文件夹内的新内容。
有人有执行此操作的脚本吗?
我尝试了以下代码,其中%ApplicationDeploymentFolderPath% = \\servername\foldername
IF EXIST %ApplicationDeploymentFolderPath%\Release (
REM Get current date time
@echo off
For /f "tokens=1-3 delims=/ " %%a in ('date /t') do (set mydate=%%c_%%b_%%a)
For /f "tokens=1-2 delims=/:" %%a in ('time /t') do (set mytime=%%a%%b)
set backup_folder=%mydate%_%mytime%
MD %ApplicationDeploymentFolderPath%\%backup_folder%
REM Copy current folder to backup folder
Copy %ApplicationDeploymentFolderPath%\Release %ApplicationDeploymentFolderPath%\%backup_folder%
REM Delete Existing Release folder
RD %ApplicationDeploymentFolderPath%\Release /S /Q
)
MD %ApplicationDeploymentFolderPath%\Release
答案 0 :(得分:1)
带有参数date
的命令 /T
以配置的国家/地区为当前用户帐户定义的格式输出当前日期。可以通过引用动态环境变量 DATE
,例如使用%DATE%
来访问完全相同的日期字符串。
带有参数time
的命令 /T
以配置的国家/地区为当前用户帐户定义的格式输出当前时间。通过引用动态环境变量 TIME
(例如,用%TIME%
)可以访问完全相同的时间字符串。
执行此命令行会发生什么?
For /f "tokens=1-3 delims=/ " %%a in ('date /t') do (set mydate=%%c_%%b_%%a)
for
和cmd.exe
分别处理批处理文件,是在后台使用%ComSpec% /c
并在'
之间使用命令行进行的另一命令处理。因此在后台执行的是在C:\Windows
中安装Windows:
C:\Windows\System32\cmd.exe /c date /t
命令 date
在后台处理此命令过程的 STDOUT 的输出分别由 FOR Windows命令处理器捕获实例执行批处理文件。
使用/
作为分配给循环变量a
,b
和c
的字符串定界符,将捕获的行分为三个子字符串,它们以相反的顺序连接在一起下划线作为定界符。
通过将'date /t'
替换为"%DATE%"
,可以更快地完成此任务。在这种情况下, FOR 处理在执行 FOR 之前已经在解析此命令行上运行cmd.exe
的情况下扩展的日期 string 。因此,无需再在后台cmd.exe
开头并捕获其输出来处理同一日期 string ,这使得批处理文件的执行速度更快。
'time /t'
也可以用"%TIME%"
替换。
但是,可以通过使用字符串替换来完全优化两个 FOR 循环,例如通过对What does %date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2% mean?的回答进行描述,例如,通过运行在命令提示符窗口中:
echo %DATE% %TIME%
此命令会根据配置的国家/地区以德语日期/时间格式在我的计算机上输出:
24.07.2019 20:15:29,90
在此输出中可以看到,由于日期字符串包含.
而不是/
,并且时间字符串包含逗号,因此原始代码无法在使用我的帐户的Windows计算机上运行。
最好使用区域独立的解决方案,如%date% produces different result in batch file when run from scheduled tasks的答案中非常详细地解释。缺点是执行wmic.exe
花费的时间远远超过cmd.exe
将日期和时间字符串重新格式化为YYYY_MM_DD_HHMM
所需的时间。但是,批处理文件很可能不是每天执行一次,因此以这种格式获取日期/时间需要花费几毫秒或一秒钟的时间,这并不重要。
在这种情况下,实际上并不需要复制整个文件夹。用以下命令重命名就足够了:
ren "%ApplicationDeploymentFolderPath%\release" "%backup_folder%"
如果由于未知原因而无法使用命令move
,也可以使用命令ren
。
但是,主要问题是缺少有关如何以及何时使用delayed expansion的知识。打开command prompt,运行set /?
,并在 IF 和 FOR 示例延迟环境变量扩展示例上阅读输出帮助说明。
这里的问题是backup_folder
在执行%backup_folder%
引用的命令行时未定义,因为所有%variable%
的出现都已被Windows命令处理器在解析整个命令时替换在执行命令 IF 之前,先以 IF 条件的(
开头的位置根据引用的环境变量的当前值阻止。
因此在现有发行文件夹上执行的是:
set backup_folder=
MD \\servername\foldername\
REM Copy current folder to backup folder
Copy \\servername\foldername\Release \\servername\foldername\
REM Delete Existing Release folder
RD \\servername\foldername\Release /S /Q
debugging the batch file可以看到这一点。
另请参阅:How does the Windows Command Interpreter (CMD.EXE) parse scripts?
解决方案是通过更改第一个 IF 条件来避免命令阻塞。
快速区域依赖解决方案:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ApplicationDeploymentFolderPath=\\servername\foldername"
if not exist "%ApplicationDeploymentFolderPath%\Release\" goto CreateFolder
ren "%ApplicationDeploymentFolderPath%\Release" "%DATE:~-4%_%DATE:~-7,2%_%DATE:~-10,2%_%TIME:~0,2%%TIME:~3,2%"
:CreateFolder
md "%ApplicationDeploymentFolderPath%\Release"
endlocal
较慢区域独立的解决方案:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ApplicationDeploymentFolderPath=\\servername\foldername"
if not exist "%ApplicationDeploymentFolderPath%\Release\" goto CreateFolder
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "BackupDateTime=%%I"
set "BackupDateTime=%BackupDateTime:~0,4%_%BackupDateTime:~4,2%_%BackupDateTime:~6,2%_%BackupDateTime:~8,4%"
ren "%ApplicationDeploymentFolderPath%\Release" "%BackupDateTime%"
:CreateFolder
md "%ApplicationDeploymentFolderPath%\Release"
endlocal
要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。
echo /?
endlocal /?
for /?
goto /?
if /?
md /?
ren /?
set /?
setlocal /?
wmic /?
wmic os /?
wmic os get /?
wmic os get localdatetime /?