1

I want to parse a directory and its subdirectories and copy all files in a target directory ignoring the original folder structure. All files shall be copied directly in the target directory.

I found a nice solution here for the Windows command line:

for /r FolderA %f in (*) do @copy "%f" target

https://stackoverflow.com/a/1502183/772434

That in general works fine, but I have duplicate files in the source directory which have the same name. There are too many files, so I can not handle those exceptions by hand.

How can I handle those files in the script automatically?
Options:

  1. overwrite files during copying
  2. keep copies and rename file e. g. by adding "__123" a number at the end of the file name
  3. compare files (MDS5 sum or similar) and create copy only if files are different.

I would prefer option 3 (compare file content and keep numbered copies only if files are really different), but I'm also interested in solutions for options 1 and 2 (more pragmatic).

Community
  • 1
  • 1
MostlyHarmless
  • 445
  • 2
  • 11
  • 21
  • thanks - good point. I've edited my question and hope it is now more clear. – MostlyHarmless Jun 25 '14 at 13:44
  • 1
    for file comparisons, you can use the `comp`command – AcidJunkie Jun 25 '14 at 14:13
  • this sounds great, unfortunately, I have no experience with programming for Windows command-line. Could you make an example how to use it? If the copy process creates an error message, as a file with the same name exists already, the script would need to compare the two and if they are identical, ignore the new one and if they are different, copy the new one and append a number to its name – MostlyHarmless Jun 25 '14 at 14:25

1 Answers1

1

Here's an approach. i haven't tested it, so i hope it works as expected. There is a global variable called CURRENT_DUPLICATE_SUFFIX. every time a file with the same name is found, but with different content, this value gets incremented and appended to the resulting file name

@echo off

SET SOURCE_DIR=C:\temp\LogAnalyzer
SET TARGET_DIR=C:\temp\test\output
SET CURRENT_DUPLICATE_SUFFIX=1

for /r "%SOURCE_DIR%" %%f in (*) do CALL :SUB1 "%%f"

GOTO END


:SUB1
    SET PURE_FILE_NAME=%~nx1
    SET TARGET_FILE_NAME=%TARGET_DIR%\%PURE_FILE_NAME%

    IF NOT EXIST "%TARGET_FILE_NAME%" (
            COPY %1 "%TARGET_DIR%"
            GOTO :EOF
    )

    REM if we are here, the target file exists.
    echo n |comp %1 "%TARGET_FILE_NAME%" >NUL 2>NUL

    REM in case the files have the same content
    IF %ERRORLEVEL%==0 GOTO :EOF

    SET TARGET_FILE_NAME=%TARGET_FILE_NAME%_%CURRENT_DUPLICATE_SUFFIX%
    SET /A CURRENT_DUPLICATE_SUFFIX=%CURRENT_DUPLICATE_SUFFIX%+1

    COPY %1 "%TARGET_FILE_NAME%

GOTO :EOF

:END

AcidJunkie
  • 1,878
  • 18
  • 21