5

我想使用 Windows 批处理文件将文件 (myfile0001.bdg) 从一个特定目录复制到另一个目录。但是我想检查目标目录中的文件是否存在,如果答案是肯定的,用0001递增文件并再次检查文件是否存在(myfile0002.bdg)等等,直到文件不存在,然后复制具有新标题的文件。

所以,如果在目标目录中,我有这些文件:

我的文件0001.bdg
我的文件0002.bdg
我的文件0003.bdg
我的文件0004.bdg
我的文件0005.bdg
我的文件0006.bdg

新文件应命名为 myfile0007.bdg。下次我将执行批处理时,新文件将是 myfile0008.bdg 等。

我知道有一个命令“如果存在”,但我不知道该怎么做。

===============

  • 我在 Windows 7 x32 下
  • 源目录是“C:\USERS\RAMBYTES\DOCUMENTS\”
  • 目标目录是“P:\BACKUP\”
  • 该文件是“MYFILE0001.BDG”
4

3 回答 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 个文件,则不会进行错误处理。如果要增加文件限制,需要调整“主”for循环和子程序中数字的“格式化”

添加前导零的技巧取自这里:https ://stackoverflow.com/a/9430912/330315

于 2013-03-03T15:40:29.043 回答
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%

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

于 2013-03-03T15:53:45.453 回答
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%"
)

解释一些部分:

  1. ~位置参数引用中的波浪号 ( ) 表示相应参数的取消引用

    有时在脚本中,波浪号后面也直接跟一个修饰符。这里使用了两个修饰符,nx。前者使参数仅扩展为相应的文件名(没有路径和扩展名),后者仅提取扩展名。

    您可以在命令的内置中了解有关修饰符的更多信息FOR(通过运行

  2. 需要环境变量,因为名称部分的fname提取只能在环境变量上完成。特别是,表达式的%fname:~-4计算结果是值的最后四个字符fname。更具体地说,它读取:提取从末尾第 4 个字符开始的子字符串,并且由于-4后面没有另一个参数,包括从该点到字符串末尾的所有字符。

    另一个外观相似的表达式 ,%fname:~0,-4%则相反:它返回fname 除了最后四个字符之外的内容。数字的含义是这样的:提取从字符串开头(偏移量 0)开始的子字符串,并跨越范围直到并包括从末尾偏移量 4 处的字符。

    这种类型的另一种表达式%counter:~1, 提取从第二个字符(即偏移量 1)开始到字符串结尾(没有第二个参数)的字符。

    运行SET /?以了解有关字符串表达式的更多信息。

  3. counter实施可能还需要解释。需要在文件名的1数字部分前面添加,以便在递增时可以正确解释和处理整个值。

    问题是,以 0 开头的数值被 CMD 命令处理器视为八进制,因此,放在1开头使其将数字解释为十进制,它实际上是。在构建目标文件的完整名称时,我们只需丢弃添加的1,这就是%counter:~1使用的 。

于 2013-03-03T16:54:29.320 回答