Windowsbatch file复制并保留重复项

我有很多的图像文件夹,我想创build一个batch file,可以查看所有这些目录及其子目录,并将每个图像复制到一个新的文件夹(在同一文件夹中的所有文件)。 我有这个工作使用下面:

md "My new folder" for /D %i in (*) do copy "%i\*" ".\My New Folder" 

不过,我也想保留重复的文件(例如,如果folder1和folder2都有名为001.jpg的图像,我想都复制到新的文件夹)。 新的文件名是什么对我没关系! 有:

 001.jpg 001(1).jpg 001(2).jpg 

将是伟大的,但即使只是重命名每个单一的文件增量计数和结束:

 1.jpg 2.jpg 3.jpg etc 

也可以。 我只需要使用标准的.bat / .cmd文件,而不需要外部软件。

谢谢你的帮助!

这应该适合你。 它在扩展后添加一个数字,但是您可以轻松地将其移到任何地方。 我复制了。\ src目录中的文件,因为如果源代码与批处理文件处于同一级别,那么批处理文件也会尝试评估test_folder。 最好的选择是对test_folder进行硬编码,这样就不会被DIR / S / B命令所遗漏

 @echo off SETLOCAL ENABLEDELAYEDEXPANSION set TESTFOLDER=test_folder md "%TESTFOLDER%" set /a counter=0 FOR /F "tokens=*" %%i IN ('DIR /S /B /AD .\src\*') DO FOR /F "tokens=*" %%j IN ('DIR /B "%%i"') DO IF EXIST ".\%TESTFOLDER%\%%j" ( set /a counter=!counter!+1 echo folder: %TESTFOLDER% copy "%%i" ".\%TESTFOLDER%\%%j_!counter!" ) ELSE copy "%%i" ".\%TESTFOLDER%\%%j" :eof 

以下脚本是aflat答案的改进版本。

该脚本需要两个参数:SourcePath TargetPath。

它将递归地将SourcePath及其子文件夹中的所有文件复制到TargetPath,并只在存在重复的情况下将增加的计数器附加到基本名称。

如果TargetPath已经存在,则会出错,因为可能已经存在具有_n后缀的名称。

如果您希望每个基本名称都有一个单独的计数器,并且/或者您希望能够复制到现有的文件夹,则需要更多的工作。

该脚本比aflat答案更强大。 例如,名字与! 工作得很好。 它也以更直接和更有效的方式实现了aflat的算法。

 ::copyFlat sourcePath TargetPath @echo off setlocal disableDelayedExpansion :: Initialize and validate arguments if "%~2" equ "" echo Error: Insufficient arguments>&2&exit /b 1 set "source=%~f1" if not exist "%source%\" echo Error: Source folder "%source%" does not exist>&2&exit /b 1 set "target=%~f2" if exist "%target%\" echo Error: Target folder "%target%" already exists>&2&exit /b 1 :: Do the work md "%target%" set /an=0 for /r "%source%" %%F in (*) do if "%%~dpF" neq "%target%\" ( if exist "%target%\%%~nxF" ( set /a n+=1 set "full=%%F" set "name=%%~nF" set "ext=%%~xF" setlocal enableDelayedExpansion copy "!full!" "!target!\!name!_!n!!ext!" >nul endlocal ) else copy "%%F" "%target%" >nul ) 

或者你可以安装git bash( https://git-for-windows.github.io/ )并运行以下命令:

 mv --backup=numbered src\*.* destinationFolder 

这将创建文件,看起来像filename.ext。〜1〜,文件名。文本。〜2〜…这可能是足够的,在我的情况下,我不喜欢丢失原来的文件扩展名,所以你可以重命名通过在目标文件夹中运行以下内容:

 ls *~ | sed 's/\(.*\)\.\(.*\)\.~\(.*\)~/mv -i & \1.\3.\2/' 

这将打印重命令如下所示:mv filename.ext。〜1〜filename.1.ext

一旦你很高兴你想要执行这些命令,再次运行相同的命令,但管道sh要像这样执行(请注意,与最终重命名相同的现有文件将被覆盖 – 但-i选项应该保护你):

  ls *~ | sed 's/\(.*\)\.\(.*\)\.~\(.*\)~/mv -i & \1.\3.\2/' | sh 

改编自这个答案( https://stackoverflow.com/a/2372739