How can I copy a statically named file to another location with increasing numerical suffixes?
I've got three files in a directory that appear via another process:
c:\result\results-a.txt
c:\result\results-b.txt
c:\result\results-c.txt
Each time they all appear, I'd like to copy them to another directory with an increasing numerical suffix/prefix, once the files are copied they can be deleted. Every time the batch file starts, it can start with the number 0 (it doesn't have to scan the target directory and continue).
Ex. 开发者_开发知识库 The first time the files all appear, the target directory might look like this:
c:\archive\results-a.0000.txt
c:\archive\results-b.0000.txt
c:\archive\results-c.0000.txt
The second time they appear, the target directory would then contain:
c:\archive\results-a.0000.txt
c:\archive\results-b.0000.txt
c:\archive\results-c.0000.txt
c:\archive\results-a.0001.txt
c:\archive\results-b.0001.txt
c:\archive\results-c.0001.txt
And so on. I'm comfortable piecing this together in a BASH enviroment, but my client requires this be done on a Windows NT (Windows 7, actually) machine. Could someone get me started?
[Edit - Answer] Thanks to Joey below, this is what I ended up coding.
@echo off
setlocal enabledelayedexpansion
set Counter=0
:loop
call :test_file %1\results1.txt
call :test_file %1\results2.txt
call :test_file %1\results3.txt
timeout 2 /nobreak >nul
call :movefiles
timeout 2 /nobreak >nul
goto loop
:test_file
timeout 2 /nobreak >nul
if not exist %1 goto :test_file
goto :eof
:lz
set LZ=000%Counter%
set LZ=%LZ:~-4%
goto :eof
:movefiles
for %%f in (C:\test\*.txt) do (
call :lz
move "%%f" "c:\tmp\c-!LZ!-%%~nxf"
)
set /a Counter+=1
goto :eof
A very nice introduction to batch programming. Thanks.
You need a few pieces for this to work.
First of all, a counter:
set Counter=0
Then a subroutine that pads the value with leading zeroes:
:lz set LZ=000%Counter% set LZ=%LZ:~-4% goto :eof
The
%LZ:~-4%
is a substring operation that retains the last four characters of the variable value. In this case this is a number, zero-padded to four places.A loop that checks for files in a certain location:
:loop if exist c:\result\*.txt call :movefiles timeout 2 /nobreak >nul goto loop
Fairly readable, this one, I guess.
A subroutine that moves the files away:
:movefiles setlocal enabledelayedexpansion for %%f in (C:\result\*.txt) do ( rem Generate the zero-padded number call :lz move "%%f" "some\target\directory\%%~nf.!LZ!%%~xf" ) endlocal rem Increment the counter for next use set /a Counter+=1 goto :eof
Piecing all that together leaves you with
@echo off
setlocal enabledelayedexpansion
set Counter=0
:loop
if exist c:\result\*.txt call :movefiles
timeout 2 /nobreak >nul
goto loop
:lz
set LZ=000%Counter%
set LZ=%LZ:~-4%
goto :eof
:movefiles
for %%f in (C:\result\*.txt) do (
call :lz
move "%%f" "some\target\directory\%%~nf.!LZ!%%~xf"
)
set /a Counter+=1
goto :eof
It can be adapted to remember its last value. However, this will only work if the batch file resides in a writable location.
@echo off
setlocal enabledelayedexpansion
set Counter=0
call :init
:loop
if exist c:\result\*.txt call :movefiles
timeout 2 /nobreak >nul
goto loop
:lz
set LZ=000%Counter%
set LZ=%LZ:~-4%
goto :eof
:movefiles
for %%f in (C:\result\*.txt) do (
call :lz
move "%%f" "some\target\directory\%%~nf.!LZ!%%~xf"
)
set /a Counter+=1
>>%~dpnx0 echo set Counter=%Counter%
goto :eof
:init
Note that the last line (:init
) must be terminated with a line break (or better two; I had some issues sometimes with just one in my testing here). This essentially creates a subroutine at the end of the batch file that sets the counter repeatedly until it arrives at its last value.
It isn't exactly fast, though. There will be one set
call per counter increment at the end, and all those will be run initially.
Here's something that should get you started. Drop this in a file called incrementName.bat
and then run it several times in succession.
@echo off
goto :start
--------------------------------------------
incrementName.bat
shows how to generate a filename with a monotonically
increasing numeric portion.
Run this several times in succession to see it in action.
Mon, 18 Apr 2011 12:51
--------------------------------------------
:START
setlocal enabledelayedexpansion
call :GETNEXTFILENAME rammalamma.txt
echo Next: %nextname%
@REM copy self to that new name.
copy %0 %nextname%
GOTO END
--------------------------------------------
:GETNEXTFILENAME
@REM this is a subroutine.
@REM %1 is the basename. This logic assumes a 3-character
@REM filename extension.
set fname=%1
set ext=%fname:~-3%
set base=%fname:~0,-4%
set idx=0
:toploop1
@set NUM=00000!idx!
set nextname=%base%.!NUM:~-5!.%ext%
if EXIST !nextname! (
if !idx! GTR 99999 goto:FAIL
set /a idx=!idx! + 1
goto:toploop1
)
)
:Success
goto:EOF
:Fail - overflow
set nextname=%base%.xxxxx.%ext%
goto:EOF
--------------------------------------------
:END
endlocal
精彩评论