1

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?

Mofi
  • 46,139
  • 17
  • 80
  • 143
Vasile Mihai
  • 103
  • 6
  • 2
    Although I said it previously, and someone decided it was not worth saying and deleted it for me, I'm going to say it again nonetheless. Please clarify the intent, currently the only way that the resulting file can contain a single line `abcdefijl` given three lines containing `abc`, `def`, and `ijl` respectively, is if none of those contain line terminators. That would be rare, (very unusual), which is why you should clarify it. Without doing so, I'm not sure how either of the two current answers can achieve your goal, because their line terminators would output results to three line files. – Compo May 22 '21 at 11:12

2 Answers2

2

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:

Mofi
  • 46,139
  • 17
  • 80
  • 143
1

Your code simply overwrites the contents of file fisx.txt with the concatenation of the last two files in the arguments list.

Rather than copy, simply append.

Overwrite fisx.txt with the first file in the arguments list and append every subsequent file (in the arguments list) to file fisx.txt

type %1 >fisx.txt
:repeat
shift
If "%1" == "" goto :end
type %1 >>fisx.txt
goto :repeat
:end
Abra
  • 19,142
  • 7
  • 29
  • 41
  • 1
    This code works for text files as asked for in the question, but does not work for binary files. But more problematic is `If "%1" == "" goto :end` which results in the error message `& was unexpected at this time.` and an exit of batch file processing by `cmd.exe` running the batch file with `file1.txt "Development & Test!.txt" file3.txt` as arguments list. – Mofi May 22 '21 at 09:56
  • Output redirection is most natural command line way to do that. I agree. – XouDo May 22 '21 at 10:46