批处理文件以基于列表移动文件,而不会覆盖旧文件和副本数 [英] Batch file to move files based on a list Without overwriting Old file and number of copies

查看:72
本文介绍了批处理文件以基于列表移动文件,而不会覆盖旧文件和副本数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a folder with files and a .txt file with a list of file names and number of copies that I need to copy from one folder to another.

该脚本正在复制文件,但是如果.txt文件具有两个相同名称的文件,它将覆盖旧文件.

The script is copying the files but if the .txt file has two files of the same name it overwrites the old file.

在列表中,我有:

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

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

This is the code I have so far:

@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

推荐答案

以下方法可以解决问题:

The following should do the trick:

@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并在

Another option if you have long filenames is the use of usebackq and surrounding the path with double quotes in the for f loop instead of analyzing the output of the type command.

函数:CopyFileIF EXIST检查文件是否存在,并使用计数器为新文件的文件名找到下一个索引.它使用路径操作使用索引构造一个新文件名.

The function :CopyFile checks the existence of the file with an IF EXIST and uses a counter to find the next index for the filename of the new file. It uses path manipulation to construct a new filename with the index.

编辑:我添加了以下可能性:从文本文件中读取所需的份数,并将该数目指定为:CopyFile函数的第二个参数.如果没有给出数字或数字不是严格的正数(大于0),则不会复制.

EDIT: I've added the possibility to read the number of copies needed from the textfile and specify that number as second argument to the :CopyFile function. If no number is given or the number is not strict positive (greater than 0), it won't make a copy.

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

PS: the "little trick" I used that will set %limit% to 0 in case the second argument is empty works because set with the /a flag will replace empty variables with 0. This won't work if you use argument variables directly though:

set /a limit=%~2

如果第二个参数为空,则

将引发错误,因为cmd解析器将用空字符串替换%~2,并且它将执行set /a limit=,这是使用/a标志的无效分配.但是,如果您使用额外的变量作为公交车:

will throw an error if the second argument is empty because the cmd parser will substitute %~2 with an empty string and it will execute set /a limit= which is an invalid assignement using the /a flag. But if you use an extra variable as transit:

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

您将让set处理变量扩展而不是cmd解释器. set将看到var变量为空(在%2为空的情况下)并将其替换为0.

you'll let set handle the variable expansion and not the cmd interpreter. The set will see that the var variable is empty (in the case %2 is empty) and will replace it with 0.

这篇关于批处理文件以基于列表移动文件,而不会覆盖旧文件和副本数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆