如何将静态命名的文件复制到具有增加的数字后缀的其他位置?

时间:2011-04-18 16:47:11

标签: windows scripting batch-file

我在目录中有三个文件通过另一个进程显示:

c:\result\results-a.txt
c:\result\results-b.txt
c:\result\results-c.txt

每次出现这些内容时,我都希望将它们复制到另一个具有增加的数字后缀/前缀的目录中,一旦复制了文件,就可以删除它们。每次批处理文件启动时,它都可以从数字0开始(它不必扫描目标目录并继续)。

实施例。文件第一次出现时,目标目录可能如下所示:

c:\archive\results-a.0000.txt
c:\archive\results-b.0000.txt
c:\archive\results-c.0000.txt

第二次出现时,目标目录将包含:

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

等等。我很乐意在BASH环境中将它拼凑在一起,但我的客户端要求在Windows NT(实际上是Windows 7)机器上完成。有人能让我开始吗?

[编辑 - 答案] 感谢下面的Joey,这就是我最终的编码。

@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

批处理编程的一个非常好的介绍。感谢。

2 个答案:

答案 0 :(得分:2)

你需要一些工作才能发挥作用。

  1. 首先,一个柜台:

    set Counter=0
    
  2. 然后一个子程序用前导零填充值:

    :lz
      set LZ=000%Counter%
      set LZ=%LZ:~-4%
    goto :eof
    

    %LZ:~-4%是一个子字符串操作,它保留变量值的最后四个字符。在这种情况下,这是一个数字,零填充到四个位置。

  3. 检查特定位置文件的循环:

    :loop
      if exist c:\result\*.txt call :movefiles
      timeout 2 /nobreak >nul
    goto loop
    

    相当可读,我猜这个。

  4. 移动文件的子程序:

    :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
    
  5. 将所有这些拼凑在一起会让您失望

    @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
    

    它可以适应记住它的最后一个值。但是,这仅在批处理文件位于可写位置时才有效。

    @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
    

    请注意,最后一行(:init)必须以换行符结束(或者更好的两行;我的测试中有时会遇到一些问题)。这实质上在批处理文件的末尾创建了一个子程序,它重复设置计数器,直到它到达最后一个值。

    但是,这并不是很快。最后每个计数器增量将有一个set个调用,所有这些都将在最初运行。

答案 1 :(得分:0)

这是应该让你开始的东西。将其放在名为incrementName.bat的文件中,然后连续多次运行。

@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