3

I've tried the following:

@echo off
REM New line.
set LF=^& echo.
set multiline=multiple%LF%lines%LF%%LF%of%LF%text

echo %multiline%

echo %multiline% > text.txt

It only saves the first line of the text.

So I suppose the only way to do this is using a for loop?

Axonn
  • 8,877
  • 5
  • 29
  • 39
  • 5
    You are not actually attempting to create a variable that contains multiple lines. Rather you are attempting to create a variable containing a "macro" that when executed produces multiple lines. There is a big difference. – dbenham Apr 11 '17 at 15:28

2 Answers2

5

Spend your script a pause after the set command - and be surprised ;)

After that, change it to:

@echo off
REM New line.
set LF=^& echo.
set "multiline=multiple%LF%lines%LF%%LF%of%LF%text"
echo %multiline%
(echo %multiline%) > text.txt
type text.txt
Stephan
  • 47,723
  • 10
  • 50
  • 81
  • I guess this is me learning batch through reading answers. So the parenthesis actually makes the entire output to go into the file. – Axonn Apr 11 '17 at 15:40
  • 2
    Yes. Else, just the last `echo` would be redirected. Some commands enclosed in parantheses is called "code block". Also see dbenhams answer for a "true" linefeed. – Stephan Apr 11 '17 at 15:54
  • Unfortunately the "true" linefeed doesn't work that well actually. It doesn't show in Notepad.exe, just in Notepad++ (for the obvious reason that Notepad.exe requires a full CRLF for new lines if I'm not mistaken). – Axonn Apr 12 '17 at 08:10
  • 1
    see (for example) [here](http://stackoverflow.com/a/29574760/2152082) how to create a `CR`: `for /F %%a in ('copy /Z "%~F0" NUL') do set CR=%%a` (to use it, also use delayed expansion: `!CR!`) – Stephan Apr 12 '17 at 10:08
  • What if I don't want to use delayed expansion? :) – Axonn Apr 12 '17 at 12:56
5

Your code never attempts to create a variable containing multiple lines of text. Rather you are attempting to create a variable that contains multiple commands (a macro) that when executed produces multiple lines of text.

Here is a simple script that truly creates a variable with multiple lines, and then writes the content to a file:

@echo off
setlocal enableDelayedExpansion

:: Create LF containing a line feed character
set ^"LF=^
%= This creates a Line Feed character =%
^"

set "multiline=multiple!LF!lines!LF!of!LF!text"
echo !multiline!
echo !multiline!>test.txt

You can read more about using line feed characters within variables at Explain how dos-batch newline variable hack works. The code I used looks different, but it works because I used an
%= undefined variable as comment =% that expands to nothing.

If you want each line to follow the Windows end of line standard of carriage return / line feed, then you need to also create a carriage return variable. There is a totally different hack for getting a carriage return.

@echo off
setlocal enableDelayedExpansion

:: Create LF containing a line feed character
set ^"LF=^
%= This creates a Line Feed character =%
^"

:: Create CR contain a carriage return character
for /f %%A in ('copy /Z "%~dpf0" nul') do set "CR=%%A"

:: Define a new line string
set "NL=!CR!!LF!

set "multiline=multiple!NL!lines!NL!of!NL!text"
echo !multiline!
echo !multiline!>test.txt
Community
  • 1
  • 1
dbenham
  • 119,153
  • 25
  • 226
  • 353
  • Even though the above script prints out fine, the contents of the text file reads out as a single line in Notepad.exe, and multiline in Notepad++. The other method of producing a line feed (^& echo.) produces line-feeds that show as line-feeds in Notepad.exe too. I suppose this is because Notepad.exe only treats full CRLF as newline, not only LF. – Axonn Apr 12 '17 at 08:08
  • 1
    @Axonn - See my updated answer with an additional hack to get a carriage return into a variable. – dbenham Apr 12 '17 at 13:08
  • Thank you for all the excellent work :). It's for a good cause (my open source literature project :) ). Just curious: is any of this possible WITHOUT enabledDelayedExpansion? Is enabledDelayedExpansion working on older Windows OSes? – Axonn Apr 12 '17 at 13:21
  • 1
    @Axonn - Delayed expansion is available to "all" versions of Windows that you are likely to run across today, certainly from XP onward. If you want to work with CR within variables, then you must use delayed expansion, and LF is also much better with delayed expansion. Using LF variable without delayed expansion requires very awkward escape sequences, which I am sure you don't want to get involved with. – dbenham Apr 12 '17 at 13:51