batch-filecmdcopybatch-rename

Batch copy multiple files from different folders with their paths listed in a txt file, and rename any duplicates


I've been trying to tackle this problem for few days now to no avail. I have no programming experience whatsoever and this task has been driving me nuts.

I have a txt file that has a list of paths to files that need to be copied. Some 8000 paths are in this file.

Copying each item isn't such a big deal as I can just add the copy command and destination before/after each path.

The crux of my issue is that many of these files have the same filename and when they're in different directories it's not a problem.

However I need all the files in the same destination folder and it keeps overwriting itself.

To sum up, I have a .txt file that basically looks like this:

D:\Big folder\Folder\Subfolder a\filea.file    
D:\Big folder\Folder3\Subfolder za\filek.file    
D:\Big folder\Folder\Subfolder ds\filed.file   
D:\Big folder8\Folder\Subfolder p\filea.file...

I need some tool that will let me copy all of these files into one destination folder, and make sure any duplicates get renamed so that they aren't overwritten.

such that filea.file and filea.file become filea.file and filea1.file

EDIT: so far I've come up with

FOR /F "tokens=* usebackq" %i IN (`type "C:\Users\username\Desktop\completelist.txt"`) DO COPY "%i" "E:\destination\"

which does the read and copy job but not the rename part


Solution

  • Save script below to Copy.bat, open Cmd Prompt from the script directory, and run the bat. It works well for me. Post exact errors, if any.

    @echo off
    setlocal enabledelayedexpansion
    set file=%userprofile%\Desktop\completelist.txt
    set "dest=E:\destination" & set "i=" & pushd !dest!
    for /f "usebackq tokens=*" %%G in ("%file%") do (
        call :rename %%~nG %%~xG %%G
        copy "%%G" "%dest%\!target!" >nul )
    popd
    exit /b
    
    :rename
    set "target=%1!i!%2"
    :loop
    set /a i+=1
    if exist "!target!" set "target=%1!i!%2" & goto :loop
    set "i=" & echo Copied %3 to !target!
    exit /b