3

I have files in subfolders which are in a folder structure is like this:

D:\Folder_Source  
D:\Folder_Source\file1.txt  
D:\Folder_Source\FolderA  
D:\Folder_Source\FolderA\file1.txt  
D:\Folder_Source\FolderA\file2.txt  
D:\Folder_Source\FolderB  
D:\Folder_Source\FolderB\file3.txt  
D:\Folder_Source\FolderB\file4.txt  
D:\Folder_Source\FolderB\file8.txt

I want to move some txt files in each subfolder to C:\Destination\ from a command prompt.

For example, the files I want to move are file1.txt, file2.txt, file8.txt, etc.

If there is a file in the destination folder with the same name of the file from the source folder being copied, I want to keep both files and not overwrite the existing file.

I tried this which fails and does not give me the expected result:

move /s file1.txt file2.txt file8.txt C:\Destination

Is something like this even possible from command line or a batch script?

2

You can use a batch script and set three variables in it with one being the path to the root source directory which will be traversed for specific files, the second being the destination path where the new files will be copied, and the third being a file list of the file names you wish to copy to the destination directory.

With these three variables you can use a FOR /R loop to traverse the source location and use conditional IF logic to check whether or not files already exist for whatever copy or delete operation needs to be performed with each file. Furthermore you can use a CALL and variable substitutions to pass the parts of the file name to another routine and use additional IF logic along with SET /A to increment the duplicate file number, etc.


Batch Script

@ECHO OFF

SET "source=C:\Folder_Source"
SET "dest=C:\Destination"
SET "FileList=file1.txt file2.txt file8.txt" 

SET "dupCnt=1"

FOR /R "%source%" %%A IN (%FileList%) DO (
    IF NOT EXIST "%dest%\%%~NXA" (
        XCOPY /F /Y "%%~FA" "%dest%\" && IF EXIST "%%~FA" DEL /Q /F "%%~FA"
    ) ELSE (
        CALL :DupeRoutine "%%~FA" "%%~NA" "%%~XA"
        )
    )
GOTO :EOF

:DupeRoutine
IF EXIST "%dest%\%~2_(%dupCnt%)%~3" (
    SET /A dupCnt=%dupCnt%+1
    CALL :DupeRoutine "%~1" "%~2" "%~3"
) ELSE (
    IF NOT EXIST "%dest%\%~2_(%dupCnt%)%~3" ECHO F | XCOPY /Y /F "%~1" "%dest%\%~2_(%dupCnt%)%~3" && DEL /Q /F "%~1"
    SET "dupCnt=1" 
    )
GOTO :EOF

Results

Note: If you wish for the duplicate file names to use another naming convention than the _(#) I used then you will need to change the _(%dupCnt%) in the script within "%dest%\%~2_(%dupCnt%)%~3" to be whatever other format you wish to use but %dupCnt% is the number that will increment. I'm happy to help further with this too.

Source Before

D:\Folder_Source
│   file1.txt
│   file2.txt
│   file4.txt
│   file8.txt
│   file99.txt
│
├───FolderA
│       file1.txt
│       file2.txt
│       file4.txt
│       file8.txt
│       file99.txt
│
└───FolderB
        file1.txt
        file2.txt
        file4.txt
        file8.txt
        file99.txt

Destination After

C:\Destination
    file1.txt
    file1_(1).txt
    file1_(2).txt
    file2.txt
    file2_(1).txt
    file2_(2).txt
    file8.txt
    file8_(1).txt
    file8_(2).txt

Source After

D:\Folder_Source
│   file4.txt
│   file99.txt
│
├───FolderA
│       file4.txt
│       file99.txt
│
└───FolderB
        file4.txt
        file99.txt

Further Resources

  • FOR /R
  • IF
  • XCOPY
  • DEL
  • CALL

  • Batch Substitutions (FOR /?)

    In addition, substitution of FOR variable references has been enhanced. You can now use the following optional syntax:

    %~I         - expands %I removing any surrounding quotes (")
    %~fI        - expands %I to a fully qualified path name
    %~nI        - expands %I to a file name only
    %~xI        - expands %I to a file extension only
    
  • SET

    Arithmetic expressions (SET /a)

    Placing expressions in "quotes" is optional for simple arithmetic but required for any expression using logical operators.

    Any SET /A calculation that returns a fractional result will be rounded down to the nearest whole integer.

    The expression to be evaluated can include the following operators:

    + Add set /a "_num=_num+5"

  • @LutfiCreativesys I used a combination of XCOPY & DEL rather than MOVE since I could put some validation conditional logic in with that command too. Also note that when you move, files will retain NTFS ACL attributes whereas when you use XCOPY it inherits the ACL attributes from the location which the files are copied. Typically you want to handle file security at a folder level so that is another reason I prefer XCOPY over MOVE although I used Robocopy a lot too, I usually don't keep dupes like this though either. Let me know if I can adjust further to accommodate your needs. – Pimp Juice IT Jan 23 at 22:11
  • 1
    Nice answer guy 👍 – Tim_Stewart Feb 7 at 19:21
  • 1
    lol regrettably, currently doing Telco contracting. Looking for full-time I.T employment. – Tim_Stewart Feb 7 at 20:10
  • why when I enter a file list of more than 500, the script doesn't work? – Lutfi Creativesys Feb 11 at 5:09
  • Does the script have limits on move files? – Lutfi Creativesys Feb 11 at 5:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.