通过在文件名中插入时间戳来复制文件比大多数人想象的要困难。请参阅Create a backup copy of files以获取详细信息和完整说明。
下面的批处理文件代码应该适用于您的任务将目录C:\RatePDF
中的* .xlsx文件与文件名中的当前本地日期和时间复制到子目录backup
。
@echo off
rem Note: Remove both /V for copying large files faster without verification.
setlocal EnableDelayedExpansion
set "SourcePath=C:\RatePDF"
if not exist "%SourcePath%\*.xlsx" exit /B
set "DestPath=%SourcePath%\backup"
rem Get local date and time in region and language independent format YYYYMMDDHHmmss.
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS get LocalDateTime /format:value') do set "LocalDateTime=%%I"
rem Reformat the local date and time to format YYYY-MM-DD_HH-mm-ss.
set "LocalDateTime=%LocalDateTime:~0,4%-%LocalDateTime:~4,2%-%LocalDateTime:~6,2%_%LocalDateTime:~8,2%-%LocalDateTime:~10,2%-%LocalDateTime:~12,2%"
rem Command COPY can't be used for copying files with either hidden or
rem system attribute set or if destination file exists already and has
rem read-only attribute set. Therefore must use the command XCOPY as this
rem command can copy also hidden and system files by using option /H,
rem with keeping the attributes of copied file by using option /K,
rem with overwriting also already existing file by using option /Y,
rem even if destination file is read-only by using option /R,
rem with verifying also successful copying of file by using option /V
rem and with automatic continuation on failure by using option /C.
rem But there is a real problem on using XCOPY for copying a single file:
rem It prompts the user if the destination is a file or a directory if the
rem destination file does not already exist. And this prompt depends on
rem language of operating system.
rem A hack is used to get the language dependent letter from prompt text
rem without really copying any file. Command XCOPY is used to start copying
rem the batch file itself to folder for temporary files with file extension
rem being TMP for destination file. This results in a prompt by XCOPY if
rem there is not already a file with that name in temporary files folder
rem which is very unlikely. The handler of device NULL is used as an input
rem handler for XCOPY resulting in breaking the copying process after the
rem prompt was output by XCOPY 2 times. This output is processed in a FOR
rem loop which is exited on first line starting with an opening parenthesis.
rem This is the line on which second character defines the letter to use
rem for specifying that destination is a file.
del /F "%TEMP%\%~n0.tmp" 2>nul
for /F %%I in ('%SystemRoot%\System32\xcopy.exe "%~f0" "%TEMP%\%~n0.tmp" ^<nul') do (
set "PromptAnswer=%%I"
if "!PromptAnswer:~0,1!" == "(" (
set "PromptAnswer=!PromptAnswer:~1,1!"
goto CreateBackups
)
)
echo ERROR: Failed to determine letter for answering prompt of XCOPY.
exit /B
:CreateBackups
if not exist "%DestPath%\" md "%DestPath%"
rem Note: Files with hidden attribute set are ignored by this FOR loop.
for %%F in ("%SourcePath%\*.xlsx") do call :CopyFile "%%~F"
exit /B
rem Subroutine for copying a single file which always has a file
rem extension because this batch file is for copying *.xlsx files.
:CopyFile
set "FileName=%~n1"
set "FileExtension=%~x1"
echo Copy "%~f1" to "%DestPath%\%FileName%_%LocalDateTime%%FileExtension%"
rem Try to copy the file with standard command COPY with verification.
copy /V /Y "%~f1" "%DestPath%\%FileName%_%LocalDateTime%%FileExtension%" >nul 2>&1
rem Copying failed if exit code of COPY is greater or equal 1.
if errorlevel 1 goto UseXcopy
echo Success
exit /B
rem Another issue to solve is that XCOPY is not reliable on error codes.
rem For example if option /R would not be used and destination file has
rem read-only attribute set, the single file copy fails with error message
rem access denied written to STDERR stream, but the exit code of XCOPY is
rem nevertheless 0 like on a successful copy. On other errors the exit code
rem is correct like write access on existing destination file fails because
rem the destination file is opened currently by an application with blocking
rem shared access completely or allows just shared read for the file.
rem So instead of evaluating the exit code, XCOPY is executed within a FOR
rem loop to evaluate the number of copied files output on last line by XCOPY
rem to STDOUT stream. The number of copied files is 1 on successful copy of
rem the single file. Any other string (number 0) is interpreted as failed
rem copy of the specified file. Output of copied files is suppressed by
rem using option /Q of XCOPY.
:UseXcopy
for /F %%I in ('echo %PromptAnswer% ^| %SystemRoot%\System32\xcopy.exe "%~f1" "%DestPath%\%FileName%_%LocalDateTime%%FileExtension%" /C /H /K /Q /R /V /Y') do set "FilesCopied=%%I"
if not "%FilesCopied%" == "1" (
echo ERROR: Creating the backup failed, see error message above.
exit /B
)
echo Success
exit /B
注1:有隐藏属性 *的.xlsx文件不与此批处理文件复制。
注2:批处理文件包含一些行,其中包含echo
打印哪个文件被复制以及复制是成功还是失败。一旦批处理文件按预期工作,您应该删除这些行。
您的错误之一是使用/R
将C:\RatePDF
中的所有* .xlsx文件递归复制到C:\RatePDF\backup
,因为目标备份目录是源目录的子目录。因此,您的批处理文件会创建副本副本的副本...有问题,不是。
为了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。
call /?
copy /?
del /?
echo /?
exit /?
for /?
goto /?
if /?
md /?
rem /?
set /?
setlocal /?
wmic OS get /?
阅读也是微软的文章Using command redirection operators和Testing for a Specific Error Level in Batch Files。
阅读并遵循[调试您的批处理文件](http://www.robvanderwoude.com/battech_debugging.php) – JosefZ
什么@JosefZ说。特别是,在调试**时,首先列出第一件事,并从文件顶部删除'echo off'。那会告诉你哪一行失败! –