Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows batch file to copy and keep duplicates

I have many folders of images, and I want to create a batch file that can look through all these directories and their subdirectories, and copy every image to a single new folder (all files in the same folder). I have this working using the below:

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

however, I also want to keep files with duplicates (for example if folder1 and folder2 both have images called 001.jpg, i want both copied to the new folder). It doesn't matter to me what the new filenames are! Having:

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

would be great, but even just renaming every single file with an incremental count and ending up with:

1.jpg
2.jpg
3.jpg
etc

would be fine too. I need it just using a standard .bat/.cmd file though, no external software.

Thanks for your help!

like image 701
David Lee Avatar asked Mar 09 '11 15:03

David Lee


1 Answers

The following script is an improved version of aflat's answer.

The script expects two arguments: SourcePath TargetPath.

It recursively copies all files from SourcePath and its subfolders to TargetPath, appending an increasing counter to the base name only if there is a duplicate.

It errors out if the TargetPath already exists because there may already exist names with the _n suffix.

More work is needed if you want a separate counter for each base name and/or if you want to be able to copy to an existing folder.

The script is more robust than the aflat answer. For example, names with ! work just fine. It also implements aflat's algorithm in a more direct and more efficient way.

::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 /a n=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
)
like image 73
dbenham Avatar answered Oct 21 '22 05:10

dbenham