Set a=%~1
echo %a%>>"C:\file.txt"
Im calling the script via cmd "C:\batch.bat" "$Multi Line String$"
The output file is only having the text till the first line break. Please Help
Set a=%~1
echo %a%>>"C:\file.txt"
Im calling the script via cmd "C:\batch.bat" "$Multi Line String$"
The output file is only having the text till the first line break. Please Help
As I said in a comment, there is no way to pass a value with multi-line text in a Batch file parameter. You should pass the name of the multi-line text variable instead and expand it using DelayedExpansion. This is an example of such a method:
@echo off
setlocal EnableDelayedExpansion
rem Create a variable with just LineFeed
set LF=^
%Don't remove%
%these two lines%
rem Create the variable with multi-line text
set "MultiLineString=Line1: Test.!LF!Line2: Testing.!LF!Line3: Tested."
rem Call the Batch script passing *THE NAME* of the variable
cmd /C batch.bat MultiLineString
And this is your same batch.bat script with the changes I suggested:
@echo off
setlocal EnableDelayedExpansion
Set a=%~1
echo !%a%!> file.txt
echo File created:
type file.txt
Output:
File created:
Line1: Test.
Line2: Testing.
Line3: Tested.
This method works as long as the calling program have stored the multi-line string in an environment variable, that is the only type of variables that can be accessed by a Batch file. For this reason, it is important for us to know how you created the multi-line string; otherwise, we have no means to solve this problem...
EDIT: New method added
After I read the improvements to jeb's answer I must admit that I was wrong: it is possible to pass the value of a multi-line variable in a Batch file parameter. This is my own version of such a method:
@echo off
setlocal EnableDelayedExpansion
rem Create a variable with just LineFeed
(set LF=^
%empty line%
)
rem Create the variable with multi-line text
set "MultiLineString=Line1: <Test>.!LF!Line2: |Testing|.!LF!Line3: &Tested&."
rem Prepare the multi-line variable and call the receiver Batch file
call :callBatch
echo Back to caller...
goto :EOF
:callBatch
rem Prepare the multi-line variable
set "lines="
for /F "delims=" %%a in ("!MultiLineString!") do (
if not defined lines (
set "lines=%%a "
) else (
set "line=%%a"
for %%b in ("&=^&" "<=^<" ">=^>" "|=^|") do set "line=!line:%%~b!"
set "lines=!lines!!LF!!line!"
)
)
REM echo [!lines!]
rem Call the receiver Batch file
(batch.bat "!lines!")
exit /B
And this is the new version of the companion batch.bat file:
@echo off
setlocal EnableDelayedExpansion
(
prompt $S
echo on
for %%a in (_) do if a==b (
%1
)
) > param.tmp
@echo off
(for /F "skip=2 delims=" %%a in (param.tmp) do if "%%a" neq ")" (
set "line=%%a"
echo(!line:~1,-2!
)) > file.txt
del param.tmp
echo File created:
echo/
type file.txt
This version correctly manage most special Batch characters, excepting exclamation-mark. This is the output:
File created:
Line1: <Test>.
Line2: |Testing|.
Line3: &Tested&.
Back to caller...
PS - This method will not work if the receiver batch.bat file is executed from outside another batch file, that is, via the standard cmd /C batch.bat "$Multi Line String$"
method.
Obviously, there is a way to to pass a value with multi-line text in a Batch file parameter.
But it is a little bit complex and currently there isn't a way to get the content out of the parameter in a safe way for any possible content.
A simple demonstration
Producer.bat - puts "Line1<line feed>Line2"
into %1
@echo off
setlocal EnableDelayedExpansion
(set LF=^
%=empty=%
)
set ^"pVar=^^^^^"Line1^^^^!LF!!LF!line2""
call Receiver.bat %%pVar%% #
Receiver.bat
@echo off
prompt :
@echo on
(
@exit /b
REM # %~1 #
)
Output
:(
REM # Line1
line2 #
)
To fetch this, the solution from How to receive even the strangest command line parameters? can be extended.
The problem is, that it only works with simple content, but there exists content which can't be received without producing parser errors.
Like: "Line1<line feed>Line2"
Therefore I would recommend Aacini's solution
Edit: Improved samples
A batch file to call another batch file with multi line variables.
@echo off
setlocal EnableDelayedExpansion
(set \n=^
%=empty=%
)
set "var=Line1!\n!line2!\n!line3!\n!line4"
call :callBatch var
exit /b
:callBatch
setlocal EnableDelayedExpansion
set "prepVar=!%~1!"
for %%L in ("!\n!") DO (
for %%b in ("^=^^" "&=^&" "<=^<" ">=^>" "|=^|") do set "prepVar=!prepVar:%%~b!"
set "prepVar=^^"!prepVar:%%~L=^^%%~L%%~L!""
)
rem echo !prepVar!-
call receiver.bat %%prepVar%%
exit /b
And a receiver.bat that accepts and parses a multi line value from %1
.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
prompt :
(
@echo on
for %%a in (4) do (
@goto :next
rem # %~1#
)
) > param.tmp
:next
@echo off
endlocal
setlocal DisableDelayedExpansion
set lineNo=0
(
for /F "skip=3 delims=" %%L in (param.tmp) do (
set /a lineNo+=1
set "line=%%L"
setlocal EnableDelayedExpansion
if !lineNo! EQU 1 (
set "line=!line:*# =!"
set "line=!line:~,-2!"
) ELSE IF "!line!"==") " (
goto :exit
) ELSE (
set "line=!line:* =!"
set "line=!line:~,-1!"
)
(echo(!line!)
endlocal
)
) > file.txt
:exit
type file.txt
Edit2: Unsolved problems
It's possible to fetch any content in line1, but all other lines have restrictions for their content.
The content has to be "parse conform", that means that a multi line parameter with this content fails
Line1
If a=
It's because the first line can be secured with REM
, but all other lines have to be valid lines.
Carets are only visible in line1 (with the REM technic).
And lines beginning with @
are empty and :
are removed completly.