Подтвердить что ты не робот

Im передает многострочный текст в качестве аргумента, который будет сохранен в переменной, а затем созданный файл имеет только 1 Lline

Set a=%~1
echo %a%>>"C:\file.txt"

Я вызываю script через cmd "C:\batch.bat" "$ Multi Line String $"

Выходной файл имеет только текст до разрыва первой строки. Пожалуйста, помогите

4b9b3361

Ответ 1

Очевидно, что есть способ передать значение с помощью многострочного текста в параметре Batch файла.
Но это немного сложно, и в настоящее время нет способа безопасно достать контент из этого параметра для любого возможного контента.

Простая демонстрация

Producer.bat - помещает "Line1<line feed>Line2" в %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 #
)

Выход

: (

REM # Line1
 line2 #
)

Чтобы получить это, можно расширить решение Как получить даже самые странные параметры командной строки?.

Проблема заключается в том, что он работает только с простым контентом, но существует контент, который не может быть получен без ошибок парсера.
Например: "Line1<line feed>Line2"

Поэтому я бы рекомендовал решение Aacini

Изменить: улучшенные образцы

Пакетный файл для вызова другого командного файла с несколькими переменными строк.

@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

И приемник .bat, который принимает и анализирует многострочное значение из %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: нерешенные проблемы
Можно получить любой контент в строке1, но все остальные строки имеют ограничения для их содержимого.
Содержимое должно быть "согласованием разбора", это означает, что параметр с несколькими линиями с этим контентом терпит неудачу.

Line1
Если a =

Это потому, что первая строка может быть защищена с помощью REM, но все остальные строки должны быть допустимыми.
Картины видны только в строке 1 (с техникой REM).
И строки, начинающиеся с @, пусты и : полностью удаляются.

Ответ 2

Как я уже сказал в комментарии, невозможно передать значение с помощью многострочного текста в параметре Batch файла. Вы должны передать имя многострочной текстовой переменной и расширить ее, используя DelayedExpansion. Это пример такого метода:

@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

И это ваш те же batch.bat script с изменениями, которые я предложил:

@echo off
setlocal EnableDelayedExpansion

Set a=%~1
echo !%a%!> file.txt

echo File created:
type file.txt

Вывод:

File created:
Line1: Test.
Line2: Testing.
Line3: Tested.

Этот метод работает до тех пор, пока вызывающая программа сохранила многострочную строку в переменной среды, которая является единственным типом переменных, к которым может обращаться пакетный файл. По этой причине нам важно знать, как вы создали многострочную строку; в противном случае у нас нет средств для решения этой проблемы...

EDIT: добавлен новый метод

После того, как я прочитал улучшения в jeb answer, я должен признать, что я ошибался: возможно передать значение многострочной переменной в пакетном файле параметр. Это моя собственная версия такого метода:

@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

И это новая версия файла batch.bat для компаньона:

@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

Эта версия правильно управляет большинством специальных символов пакета, кроме восклицательного знака. Это результат:

File created:

Line1: <Test>.
Line2: |Testing|.
Line3: &Tested&.

Back to caller...

PS - этот метод не будет работать, если файл-ресивер batch.bat выполняется из внешнего командного файла, то есть с помощью стандартного метода cmd /C batch.bat "$Multi Line String$".