How to parse multiple lines from a .txt file and put them in a single line using batch script

I have a .txt file which contains a list of, let's say, numbers, one on each line. I want to parse that .txt file and put all those numbers in a single line, separated by a space. What i tried so far, was just to see if i can parse the lines from a text, but it doesn't seem to work. I tried this command:

C:\Users\Adi>for /F "tokens=*" %A in ("file.txt") do (set line=%G echo !line!)

but as result i get just:

C:\Users\Adi>(set line=file.txt echo !line!)

Content of my .txt file:

685576
685569
685564
685265
685229
685222
685121
684189
683905
681508
681321
680799
680436
679650
679424

I would like to have those all in a single line, separated by a space. Can you please tell me whee i go wrong? Thank you!

To mention that my .txt has more that 100 lines. Not sure if this may impact in some way! Thank you!

Adi C

Upvotes: 0

Views: 853

Answers (2)

aschipfl
aschipfl

Reputation: 34899

A simple way of appending multiple lines of a text file to a single one is to append them in a variable and to output its content at once, as shown in the other answer -- although I would prefer delayed expansion over call due to better performance and safety against special characters:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_SOURCE=%~dpn0.txt"    & rem // (path of source file)
set "_TARGET=%~dp0line.txt" & rem // (path of target file)
set "_SEPCHR= "             & rem // (separator character)

rem // Initialise buffers:
set "COLL=" & set "SEP="
for /F usebackq^ delims^=^ eol^= %%L in ("%_SOURCE%") do (
    rem // Store current line:
    set "LINE=%%L"
    rem /* Use delayed expansion to append lint to buffer in order to avoid
    rem    trouble with special characters; use a `for /F` loop to transport
    rem    the buffer beyond the `endlocal` barrier: */
    setlocal EnableDelayedExpansion
    for /F delims^=^ eol^= %%K in ("!COLL!!SEP!!LINE!") do (
        endlocal & set "COLL=%%K"
    )
    rem // Apply separator character only after the first line:
    set "SEP=%_SEPCHR%"
)
rem // Write collected buffer data into target file:
setlocal EnableDelayedExpansion
> "!_TARGET!" echo(!COLL!
endlocal

endlocal
exit /B

However, the above approach fails if the total length of the build output line exceeds about 8190 bytes or characters.

Here is an improved version, which does not limit the length of the output line; the line lengths of the input file is still limited to about 8190 bytes/characters though:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_SOURCE=%~dpn0.txt"    & rem // (path of source file)
set "_TARGET=%~dp0line.txt" & rem // (path of target file)
set "_TMPLIN=%~dp0line.tmp" & rem // (path of temporary file)
set "_SEPCHR= "             & rem // (separator character)

rem // Store an EOF (end-of-file) character in a variable:
for /F %%K in ('forfiles /P "%~dp0." /M "%~nx0" /C "cmd /C echo/0x1A"') do set "EOF=%%K"
rem // Ensure the target file to exist and to be empty:
> "%_TARGET%" rem/
rem // Read source file line by line:
set "FIRST=#"
for /F usebackq^ delims^=^ eol^= %%L in ("%_SOURCE%") do (
    rem // Write current line into temporary file with an EOF character appended:
    > "%_TMPLIN%" (
        if defined FIRST (
            rem // Do not prepend a separator character to first line:
            echo(%%L%EOF%
            set "FIRST="
        ) else (
            rem // Do prepend a separator character to every other line:
            echo(%_SEPCHR%%%L%EOF%
        )
    )
    rem /* Append content of temporary file to target file; since EOF characters and
    rem    everything behind are ignored in text mode (`/A`), also the line-breaks
    rem    introduced by `echo` are not included in the output; to avoid a final EOF
    rem    character to be appended, the target file must be declared binary (`/B`): */
    > nul copy /A "%_TARGET%" + "%_TMPLIN%" "%_TARGET%" /B
)
rem // Clean up temporary file:
del "%_TMPLIN%"

endlocal
exit /B

Upvotes: 0

Compo
Compo

Reputation: 38579

Here is a full batch file to hopefully achieve what you want:

@For /F "UseBackQ Delims=" %%A In ("myFiles.txt") Do @Call Set "line=%%line%% %%A"
@Echo(%line:~1%&@Pause

Upvotes: 1

Related Questions