windows - Windows批处理命令创建备份文件夹和替换文件夹
问题描述
我需要用日期时间戳备份现有文件夹,并用文件夹内的新内容替换它(删除并重新创建)。
有没有人有脚本可以做到这一点?
我尝试了以下代码,其中%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
解决方案
带有参数的命令 以当前用户帐户配置的国家/地区定义的格式输出当前日期。可以通过引用动态环境变量来访问完全相同的日期字符串,例如使用.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
,使用'
. 因此在后台执行如下安装 Windows C:\Windows
:
C:\Windows\System32\cmd.exe /c date /t
在后台处理该命令进程的STDOUT的命令 输出由FOR分别执行批处理文件的 Windows 命令处理器实例捕获。date
/
捕获的行使用分配给循环变量的字符串分隔符分成三个子字符串a
,b
并c
以下划线作为分隔符以相反的顺序连接在一起。
'date /t'
通过替换 可以更快地完成此任务"%DATE%"
。在这种情况下, FOR在执行FOR之前处理已在解析此命令行时已运行扩展的日期字符串。因此,不再需要在后台启动并捕获其输出只是为了处理相同的日期字符串,这使得批处理文件的执行速度更快一些。cmd.exe
cmd.exe
'time /t'
可以替换为 也是如此"%TIME%"
。
但是可以通过使用字符串替换来完全优化两个FOR循环,例如通过回答What does %date:~-4,4%%date:~-10,2%%date:~-7,2% _%time:~0,2%%time:~3,2% 是什么意思?和地区相关的日期和时间格式是众所周知的,例如通过在命令提示符窗口中运行:
echo %DATE% %TIME%
此命令根据配置的国家/地区以德语日期/时间格式在我的计算机上输出:
24.07.2019 20:15:29,90
在此输出中可以看出,原始代码在我的 Windows 计算机上无法使用我的帐户,因为日期字符串包含.
而不是/
时间字符串包含逗号。
所以最好使用区域独立的解决方案,正如在回答为什么 %date% 在作为计划任务执行的批处理文件中产生不同的结果中非常详细地解释的那样?缺点是执行wmic.exe
所需的时间比cmd.exe
将日期和时间字符串重新格式化为yyyy_MM_dd_HHmm
. 但是,批处理文件很可能不是每天执行一次,因此执行以这种格式获取日期/时间是否需要几毫秒或大约一秒并不重要。
在这种情况下,实际上不需要复制整个文件夹。将其重命名为:
ren "%ApplicationDeploymentFolderPath%\release" "%backup_folder%"
move
如果ren
由于未知原因无法使用命令,也可以使用该命令。
但是,主要问题是缺少有关如何以及何时使用延迟扩展的知识。打开命令提示符,运行并阅读关于IF和FOR示例延迟环境变量扩展set /?
的输出帮助说明。
这里的问题是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
这可以通过调试批处理文件看出。
另请参阅:Windows 命令解释器 (CMD.EXE) 如何解析脚本?
解决方案是通过更改第一个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 /?