Search code examples
batch-filecmd

How to copy n files together to a new file of which names are passed as parameters to a batch file?


I try to copy n files together to a new file of which file names are passed as parameters to a .bat file. But the batch file overwrites the results file instead of concatenating the file contents on each iteration of the GOTO loop.

The batch file is:

:repeat
shift
If "%1" =="" goto :end
copy /y %0+%1 fisx.txt
goto :repeat
:end

For example:
If file1.txt has the content abc, file2.txt has the content def and file3.txt has the content ijl, the output is defijl instead of wanted adcdefijl on calling the batch file with file1.txt file2.txt file3.txt.

Are there any parameters that I need to add to not overwrite or how should I solve this?


Solution

  • The copying loop cannot work by design as expected by you. Let´s say the batch file is called with the arguments file1.txt file2.txt file3.txt. What does happen now?

    The string used to call the batch file (argument 0) is replaced by file1.txt (argument 1) and the other two arguments are also shifted left in the arguments list. Therefore file1.txt and file2.txt are copied together to file fisx.txt.

    On next loop iteration file1.txt (argument 0) is replaced by file2.txt and file3.txt becomes argument 1. Then are copied together file2.txt and file3.txt to file fisx.txt. So the content of file1.txt is ignored completely on this second copying operation as neither existing fisx.txt nor file1.txt is used on second copying operation replacing existing file fisx.txt from the first copying operation.

    The working code is:

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    if "%~1" == "" exit /B
    copy /B /Y %1 "fisx.txt" >nul
    :Repeat
    shift
    if "%~1" == "" exit /B
    copy /B /Y "fisx.txt"+%1 "fisx.txt" >nul
    goto Repeat
    

    The more enhanced version below supports also empty argument strings and a not correct quoted last argument string.

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    :FindFirst
    set "NextFile=%~1"
    if defined NextFile goto CopyFirst
    set "NextFile=%1"
    if not defined NextFile exit /B
    shift
    goto FindFirst
    :CopyFirst
    copy /B /Y "%NextFile:"=%" "fisx.txt" >nul
    :Repeat
    shift
    set "NextFile=%~1"
    if defined NextFile copy /B /Y "fisx.txt"+"%NextFile:"=%" "fisx.txt" >nul & goto Repeat
    set "NextFile=%1"
    if defined NextFile goto Repeat
    

    This version of the code supports also an argument list like:

    "" "" file1.txt "" "file2.txt" file3.txt"
    

    To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.

    • call /? ... explains referencing batch file arguments.
    • copy /?
    • echo /?
    • endlocal /? ... called implicitly by cmd.exe before exiting processing of the batch file.
    • exit /?
    • goto /?
    • if /?
    • set /?
    • setlocal /?
    • shift /?

    See also: