基于列表移动文件的批处理文件不覆盖旧文件和副本数

时间:2017-01-28 19:16:08

标签: batch-file

我有一个包含文件的文件夹和一个.txt文件,其中包含我需要从一个文件夹复制到另一个文件夹的文件名和副本数列表。

脚本正在复制文件,但如果.txt文件有两个同名文件,则会覆盖旧文件。

在列表中我有:

file1.txt 1
file2.txt 1
file1.txt 3
file2.txt 2

我希望实现以下目标:

file1.txt
file2.txt
file1(1).txt
file1(2).txt
file1(3).txt
file2(1).txt

这是我到目前为止的代码:

@echo off
set Source=C:\Users\siddique.gaffar\Desktop\Artworks
set Target=C:\Users\siddique.gaffar\Desktop\Artworks Copy
set FileList=C:\Users\siddique.gaffar\Desktop\Artwork TXT File\Book1.txt
echo.

if not exist "%Source%" echo Source folder "%Source%" not found & goto Exit
if not exist "%FileList%" echo File list "%FileList%" not found & goto Exit
if not exist "%Target%" md "%Target%"

for /F "delims=" %%a in ('type "%FileList%"') do copy "%Source%\%%a" "%Target%"


:Exit
echo.
echo press the Space Bar to close this window.
pause > nul

2 个答案:

答案 0 :(得分:0)

@echo off
set "Source=C:\Users\siddique.gaffar\Desktop\Artworks"
set "Target=C:\Users\siddique.gaffar\Desktop\Artworks Copy"
set "FileList=C:\Users\siddique.gaffar\Desktop\Artwork TXT File\Book1.txt"
setlocal EnableDelayedExpansion
for /f "delims=" %%a in ('type "%FileList%"') do (
if not defined count set "count=1"
cd "%Target%"
if exist %%a (
set "curfile=%%a"
set "curfile=!curfile:~0,-4!"
set "curfile=!curfile!(!count!).txt"
if exist !curfile! (
set /a "count=!count! + 1"
set "curfile=%%a"
set "curfile=!curfile:~0,-4"
set "curfile=!curfile!(!count!).txt"
)
cd "%Source%"
ren "%Source%\%%a" "!curfile!"
xcopy "%Source%\!curfile!" "%Target%"
ren "%source%\!curfile!" "%%a"
) else (
xcopy "%Source%\%%a" "%Target%"
)
)
pause

用此代码替换所有代码。将此批处理文件放在要复制的文件所在的目录中。 p。 s。:现在它仅适用于.txt文件。

答案 1 :(得分:0)

以下应该可以解决问题:

@echo off 
set Source=C:\Users\siddique.gaffar\Desktop\Artworks
set Target=C:\Users\siddique.gaffar\Desktop\Artworks Copy
set FileList=C:\Users\siddique.gaffar\Desktop\Artwork TXT File\Book1.txt
echo.
if not exist "%Source%" echo Source folder "%Source%" not found & goto Exit 
if not exist "%FileList%" echo File list "%FileList%" not found & goto Exit
if not exist "%Target%" md "%Target%" 

for /F "usebackq tokens=1-2" %%a in ("%FileList%") do call :CopyFile "%%a" %%b


:Exit
echo.
echo press the Space Bar to close this window.
pause > nul
exit /b 0

:CopyFile
:: first argument  = filename
:: second argument = number of copies

REM A little trick that will put limit on 0 if second argument is empty or not a number
set secondarg=%~2
set /a limit=secondarg

REM if limit is invalid (not strict positive), exit the function
IF %limit% LEQ 0 (
    echo Invalid number of copies
    exit /b 1
)
IF NOT EXIST "%Target%\%~1" (
    copy "%Source%\%~1" "%Target%"
    IF %limit% LEQ 1 exit /b 0
    set /a limit-=1
)

REM File already exists: search correct index for filename
set index=0
set "targetfile=%target%\%~n1"
set file_ext=%~x1

:following
set /a index+=1
Rem if file with index %index% already exists, go back to get following index
IF exist "%targetfile%(%index%).%file_ext%" goto :following

Rem we have the correct index, now we can copy
set /a limit=index+limit-1
FOR /L %%g IN (%index%,1,%limit%) DO copy "%Source%\%~1" "%targetfile%(%%g).%file_ext%"
exit /b 0

如果您有长文件名,则另一个选项是使用usebackq并在for f循环中使用双引号包围路径,而不是分析type命令的输出。

函数:CopyFile使用IF EXIST检查文件是否存在,并使用计数器查找新文件文件名的下一个索引。它使用path manipulation来构造带索引的新文件名。

编辑:我已经添加了从文本文件中读取所需副本数量的可能性,并将该数字指定为:CopyFile函数的第二个参数。如果没有给出数字或者数字不是严格正数(大于0),它就不会复制。

PS:"小技巧"我使用它会将%limit%设置为0,以防第二个参数为空,因为带有set标志的/a将用0替换空变量。如果你不行,这将不起作用直接使用参数变量:

set /a limit=%~2
如果第二个参数为空,

将抛出错误,因为cmd解析器将使用空字符串替换%~2,并且它将执行set /a limit=,这是使用/a标志的无效分配。但是如果你使用额外的变量作为传输:

set var=%~2
set /a limit=var

你让set处理变量扩展而不是cmd解释器。 set会看到var变量为空(如果%2为空)并将其替换为0.