Windows:复制一个文件直到文件不存在

5
我想使用一个Windows批处理文件将一个文件(myfile0001.bdg)从一个特定的目录复制到另一个目录。但我想检查目标目录中的文件是否存在,如果答案是肯定的,则增加0001文件并再次检查文件是否存在(myfile0002.bdg),直到文件不存在,并复制新标题的文件。
因此,如果在目标目录中,我有这些文件:
myfile0001.bdg myfile0002.bdg myfile0003.bdg myfile0004.bdg myfile0005.bdg myfile0006.bdg
新文件应命名为myfile0007.bdg。下一次执行批处理时,新文件将是myfile0008.bdg等等。
我知道有一个命令“IF EXIST”,但我不知道如何满足我的需求。
==============
我使用的操作系统是Windows 7 x32 源目录是 "C:\USERS\RAMBYTES\DOCUMENTS\" 目标目录是 "P:\BACKUP\" 文件名是 "MYFILE0001.BDG"
3个回答

1
像这样的东西:
@echo off

set source_file=C:\USERS\RAMBYTES\DOCUMENTS\MYFILE0001.BDG
set target_dir=P:\BACKUP\
set done=0

for /l %%i in (1,1,1000) do (
   call :check_and_copy %%i
   if errorlevel 1 goto :eof
)

goto :eof

:check_and_copy
  setlocal EnableDelayedExpansion
  set num=000000%1
  set fnum=!num:~-4!

  set fname=%target_dir%\myfile%fnum%.bdg
  rem echo %fname%
  if not exist "%fname%" (
     echo copying %source_file% to %fname%
     exit /b 1
  )
  exit /b 0

如果目标目录中存在超过1000个文件,则没有错误处理。如果您想增加文件限制,您需要调整“main”循环和子程序中数字的“格式化”。

添加前导零的技巧来自于这里:https://dev59.com/12ox5IYBdhLWcg3wGwpo#9430912


1
@ECHO OFF
SET destdir=c:\destdir
SET newname=myfile0000
FOR /f %%i IN (' dir /b /on %destdir%\myfile????.bdg ' ) DO SET newname=%%~ni
SET newname=1%newname:~-4%
SET /a newname+=1
SET newname=myfile%newname:~-4%.bdg
COPY myfile0001.bdg %destdir%\%newname%

根据需要更改目标目录,并在必要时包括源目录。


使用 dir 查找上次使用的最后一个名称是个好主意。但请注意,此方法忽略了源文件编号可能比目标目录中的最后一个名称的编号大得足够多的事实。即,最终名称中的编号将基于 %destdir% 中的最后一个名称计算。 - Andriy M

0
  1. 获取文件名。

  2. 提取数字部分。

  3. 检查相应的目标名称是否存在。

  4. 如果存在,

    4.1) 增加数字部分;

    4.2) 如果不超过最大可能数字,请转到步骤3;

    4.3) 否则终止。

  5. 如果目标名称不存在,则复制具有当前数字部分的文件并终止。

尽管在算法上,条件4.2可能更自然地在增加数字部分后立即进行检查,就像我上面所写的那样,但下面的脚本在循环开始之前的不同点处执行检查,该循环在从源文件名提取原始数字值后立即开始。在实现上,这对我来说更方便。

在所有其他方面,脚本实现了相同的算法:

@ECHO OFF
SET "fname=%~n1"
SET counter=1%fname:~-4%
:loop
IF %counter% GTR 19999 (
  1>&2 ECHO Cannot copy the file: no free slots.
  EXIT /B 1
)
SET "targetname=%~2\%fname:~0,-4%%counter:~1%%~x1"
IF EXIST "%targetname%" (
  SET /A counter+=1
  GOTO loop
) ELSE (
  COPY %1 "%targetname%"
)

解释一些部分:

引用位置参数时波浪号(~)表示对相应参数的去引号。有时在脚本中,波浪号直接跟随一个修饰符。这里使用了两个修饰符n和x。前者将参数扩展为相应文件名而不包括路径和扩展名,后者仅提取扩展名。需要使用fname环境变量来提取名称部分,因为只能在环境变量上执行此操作。特别是% fname:〜-4表达式会计算fname值的最后四个字符。另一个类似的表达式% fname:〜0,-4%则做相反的操作:返回文件名的内容,但不包括最后四个字符。数字的含义是从字符串开头(偏移量0)开始提取子字符串,并跨越到并包括偏移量末尾的第4个字符。还有一种这种类型的表达式%counter:〜1,它提取从第二个字符(即偏移量1)开始到字符串结尾的字符(没有第二个参数)。在文件名的数值部分前面添加1是因为在CMD命令处理器中以0开头的数值被视为八进制。因此,在数字前面放置1使其将该数字解释为十进制,这就是完整目标文件名的构建方式。通过简单地丢弃添加的1来完成这个任务,这就是使用%counter:〜1的原因。运行SET /?以了解有关字符串表达式的更多信息。

非常感谢您的帮助...我会在这个星期尝试!我会尽快给你一些消息。 - user2129046

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接