Reputation: 55
I am trying to copy a file from one directory to another using windows batch script and appending a time stamp to it. It works only once when the target directory is empty. if i run the batch script again then it says File not found in the specified directory. The strange thing is that when i concatenate the original file name with the time stamp then next time it looks for file name with concatenated string in the source directory. Please help.
@echo off
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set dt=%%a
set YYYY=%dt:~0,4%
set MM=%dt:~4,2%
set DD=%dt:~6,2%
set HH=%dt:~8,2%
set Min=%dt:~10,2%
set Sec=%dt:~12,2%
set stamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%
SET "destpath=C:\RatePDF\backup\"
SET "sourcepath=C:\RatePDF\"
for /r "%sourcepath%" %%f in (*.xlsx) do (
SET name=%%~nf
)
echo %name%
SET newFileName = %name%-%stamp%
COPY "%sourcepath%\%name%.xlsx" "%destpath%\%newFileName%.xlsx"
pause
Upvotes: 0
Views: 744
Reputation: 79982
Two problems that I see.
First one is that your for /r
will set name
to the very last filename found in your directory-tree founded at sourcedir
.
Since your destination directory is within your source tree, the name found is likely to be the name of the file you created in your previous run.
hence, the first run copies sourcepath=C:\RatePDF\file.txt
to C:\RatePDF\backup\file.txt-2016-03-03-18-36
(or something like that)
all fine and good, but on the second run, the last filename detected would be file.txt-2016-03-03-18-36
- but that is in C:\RatePDF\backup
not ``C:\RatePDFhence the
file missing` report.
Solution : lose the /r
Next problem:
SET newFileName = %name%-%stamp%
sets a variable newFileNamespace to a value of space%name%-%stamp%
Thus the line
COPY "%sourcepath%\%name%.xlsx" "%destpath%\%newFileName%.xlsx"
will substitute nothing into the destination filename for newfilename
since it is undefined.
Solution : lose the two stray spaces in the set
command.
Upvotes: 0
Reputation: 49086
Copying a file with inserting in file name a time stamp is more difficult than most people think. Take a look on Create a backup copy of files for details and a complete description.
The batch file code below should work for your task copying *.xlsx files in directory C:\RatePDF
with current local date and time in file name to subdirectory 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
Note 1: *.xlsx files with hidden attribute set are not copied with this batch file.
Note 2: The batch file contains some lines with echo
printing which file is copied and if that copy was successful or failed. Once the batch file is working as expected, you should remove those lines.
One of your mistakes was using /R
for recursive copying all *.xlsx files in C:\RatePDF
to C:\RatePDF\backup
because the destination backup directory is a subdirectory of source directory. So your batch file would create a copy of a copy of a copy of a copy ... There is a problem, isn't it.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
copy /?
del /?
echo /?
exit /?
for /?
goto /?
if /?
md /?
rem /?
set /?
setlocal /?
wmic OS get /?
Read also the Microsoft articles Using command redirection operators and Testing for a Specific Error Level in Batch Files.
Upvotes: 1