-4

I am trying to move files to a particular folder (destination folder), but I do not want to overwrite any files. Instead, if the file already exist in that particular folder (destination folder), then move that file in another folder (overflow folder), but keep folder structure.

I tried with xcopy and robocopy, but It appears that it can't be done like that.

This is the script I use to move files but not overwrite.

robocopy "C:\DummySourcePath\" "C:\DummyDestantionPath\" /E /XC /XN /XO
michael_heath
  • 5,262
  • 2
  • 12
  • 22
Rone Johnson
  • 1
  • 1
  • 1

2 Answers2

1

Now it looks like your goal is to take a folder or directory and take all contents from this folder (including from sub-directory's) and copy it to one main folder. Any duplicate files you want rather to be sent to an overflow rather then to be overwritten.

If you don't want to overwright any files, an overflow folder will work. However what if there are two duplicate files trying to be dumped into the overflow directory? To get around this, we can simply name {File} to {File}(1), {File}(2), exc. This part of the script was taken from michael_heath on the post - batch script to copy files listed in a txt document and keep duplicates.

Essentially we are using an FOR /R statement along with an IF statement to check if the target directory contains the file or not. If it does, the ELSE will move it to overflow with further anti-overwright protections.

@ECHO OFF
@setlocal enableextensions enabledelayedexpansion

rem | Configure directories
set "source=C:\Source-Directory"
set "target=C:\Target-Directory"
set "overflow=Overflow-Directory"

rem | Scan target directory for a duplicate file name.
rem | If a duplicate was found, run a function to copy it to a overflow directory.
rem | If it already exists in the overflow directory rename it to {Name}(1), {Name}(2), exc.
rem | The overflow {Name}(1) protection was originally scripted by: michael_heath
FOR /R "%source%" %%i in (*.*) do (
If not exist "%target%\%%~nxi" (copy "%%i" "%target%") ELSE (call :index "%%~i" "%overflow%\%%~nxi" "1"))

rem | Run finished code here or end script with "goto :eof"
goto :eof

:index  source, overflow, count
setlocal
set /a "cnt=%~3"

if exist "%overflow%\%~n2(%cnt%)%~x2" (
    call :index "%~1" "%~2" "%cnt%+1"
) else copy "%~1" "%overflow%\%~n2(%cnt%)%~x2"
John Kens
  • 1,615
  • 2
  • 10
  • 28
  • That is great and thanks to michael_heath aswell, however one issue I see is that it does not keep the folder structure, rather dumps all into the same main folder, instead of being moved/copied to its same subfolders. – Rone Johnson Sep 23 '18 at 03:04
  • @RoneJohnson That's what threw me off. Why would you need an overflow folder if you're just coping A folder. So you're wanting to check if the main directory already exists in the destination? Then either copy over or send to overflow (Overflow also maintaining file structure)? – John Kens Sep 23 '18 at 03:11
  • the files are timestamp sensitive, so I cant overwrite them. The files in the source are the Originals, the files I am moving to the destination are the originals aswell so new orginals get their slot in the orginal folders, and duplicate or edited version go to overflow. I would liek to keep folder structure intact only to the last folder node/name. i.e. C:\house\folderwewanttokeep\files.mp4 to G:\storage\folderwewanttokeep\files.mp4 where the folder "folderwewanttokeep" is the only part of the folder path we want to keep. so we can move "folderwewanttokeep\files.mp4" to wherever we decide – Rone Johnson Sep 23 '18 at 03:36
1
@echo off
setlocal

set "source=%cd%\source"
set "target=%cd%\target"
set "overflow=%cd%\overflow"

for /r "%source%" %%A in (*.*) do call :copyfile "%%~A" "move" "report"

2>nul rd "%source%"
exit /b

:copyfile  source [, operation [, report]]
setlocal
set "curpath=%~1"
set "operation=%~2"
set "report=%~3"

if defined report echo "%curpath%"

call set "destpath=%%curpath:%source%=%target%%%"
if exist "%destpath%" call set "destpath=%%curpath:%source%=%overflow%%%"

if exist "%destpath%" (
    if defined report echo     exist in "%destpath%"
    exit /b 1
)

if "%operation%" == "copy" (
    if defined report echo     copy to "%destpath%"
    echo f|>nul xcopy "%curpath%" "%destpath%"
) else (
    for %%A in ("%destpath%") do (
        if not exist "%%~dpA" md "%%~dpA" || (
            if defined report echo     md failed with "%%~dpA"
            exit /b 1
        )
    )

    if defined report (
        echo     move to "%destpath%"
        move "%curpath%" "%destpath%"
    ) else >nul move "%curpath%" "%destpath%"

    for %%A in ("%curpath%") do 2>nul rd "%%~dpA"
)
exit /b 0

move on same partition is a move in the master file table only. move to different partition is an actual copy and delete on successful copy. copy always does copy.

I implemented both operations and can be set by the 2nd optional argument to the called label of :copyfile by passing "move" or "copy". "move" is default if argument is not "copy".

The 3rd optional argument to the label :copyfile is to output a progress report. This argument if defined, will echo information (like paths etc.) about the operation.

The 1st argument to the label :copyfile is the path to the file to be copied or moved.

The for /r loop recurses the source directory and calls :copyfile with the path of each file found. :copyfile will set curpath to the source file and will set destpath to the path to target, which is the source path substituted with target path. If destpath exist, then destpath is set to the path to overflow, which is the source path substituted with overflow path. If still destpath exist, then the label is exited.

The move operation uses rd to remove empty folders from source.

The copy operation uses xcopy as it makes the destination folder structure so that md is not used. The echo f piped to xcopy is to answer the "file or folder?" prompt.

At end of script, the source folder will be removed if empty.

Set the source, target and overflow variables at the top of the script to the actual paths.

View set /? about variable substitution used in the script. It is used to replace the source directory path with the another directory path, to create the destination path.

michael_heath
  • 5,262
  • 2
  • 12
  • 22
  • Thanks seems to do the trick, I appericate the entire write out of explanation cause at first glace I was lil overwhelmed, but as i read it and took it line by line it all made sense. – Rone Johnson Sep 24 '18 at 23:57