Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I need the equivalent of the shell command xargs < list.txt cat -- > compiled.txt as a Windows batch file.

There is a directory full of text files (about 50 to 500 files) that I need to concatenate into one file. The order is important. The files can't be named in asciibetical order, because the natural order is not the order it should be compiled in the target file.

I had the the idea to name the source files like $DISREGARD1_$SECOND-ORDER_$FIRST-ORDER_$THIRD-ORDER_$DISREGARD2.txt and do some voodoo with it, but I think for my use case it is simpler and less volatile to maintain an ordered list. Concatenating from a list is very easy with xargs and cat. How do I do it with a .bat file on Windows?

I need it as an idempotent batch file so that the user can click on it. In the target file should be no command output, superfluous carriage returns or anything else that's not in the sources (i.e. like if the files were binary).

Bonus question: It would be great to allow remarks in the list file (empty lines not allowed in order to limit complexity). I'd do that on shell with sth. like grep -v ^# < list.txt | xargs cat -- > compiled.txt. Any chance to get this into a .bat file as well?

share|improve this question

2 Answers 2

up vote 1 down vote accepted

This should do it:

@echo off
REM create empty result file
copy nul results.txt /y

REM iterate over list skipping #entries and copy binary
for /f "usebackq delims=" %%F in (`findstr /R /V "^#" list.txt`) do (
 copy /b results.txt+"%%~F" results.txt 
)

Syntax as it's batch file, if you want to execute directly from cmd line change %%F to %F

share|improve this answer
    
Accepted this answer, because it also solves the remarks thing. With the learnt lessons on batch files through this question, I am able to combine your script with the script by @grawity into one that doesn't copy everything on each iteration. –  JoBo Jun 16 at 13:11
    
@JoBo I used it mainly to show different options available. Please also note that the order is important (dest+source dest, source+dest dest will not work) and it's recognized as append and optimized by cmd interpreter so it's pretty efective –  wmz Jun 16 at 15:32

Use a for loop:

@echo off

( for /f "tokens=*" %%i in (list.txt) do type "%%~i" ) > compiled.txt
share|improve this answer
1  
I have created a test case with for i in $(seq -w 0000 9999); do PREFIX=$(pwgen 8 1); echo $i > $PREFIX-$i.txt; echo $PREFIX-$i.txt >> list.txt; done. Result are files with random $PREFIX and serial suffix ($i) and with suffix as each file's content. xargs/cat generates a file with 0000\n0001\n0002\n and so forth. This batch file produces \r\n\C:\concat>type "jiesaeyi-0000.txt"\r\n0000\r\n\r\nC:\concat>type "sohsaiph-0001.txt"\r\n0001\r\n\r\n and so forth. –  JoBo Jun 16 at 9:36
1  
NOTE: In the above example %%i is used. A %% variable is only used when inside a batch file. If the command is executed from the commandprompt directly, use %i instead (on both occassions) –  LPChip Jun 16 at 9:46
    
actually \n\r\n (LFCRLF) after each four digit number –  JoBo Jun 16 at 9:47
1  
Ah, yeah, I assumed you'd use this as just a part of existing batch script, with @echo off and all. Updated. –  grawity Jun 16 at 12:19
3  
@JoBo To skip lines containing # and to handle a file list name that contain spaces, change the for command like this: for /f "usebackq eol=# delims=" %%i in ("my list.txt") do type "%%~i" –  and31415 Jun 16 at 13:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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