Пакет: объединить две произвольные строки за пределами SETLOCAL EnableDelayedExpansion - PullRequest
3 голосов
/ 23 февраля 2012

Мне нужно объединить две строковые переменные и поместить результат обратно в первую переменную.Эти две строки могут содержать любые произвольные символы, такие как символ новой строки, восклицательный знак и т. Д.

Основной сценарий запускается с отложенным расширением отключено , поэтому я должен использовать SETLOCAL EnableDelayedExpansion для фактической конкатенации.Я просто не знаю, как вернуть результат из локальной и глобальной переменной.

Я бы хотел не использовать временные файлы.

Я бы хотел, чтобы пакетные файлы допускали отложенное расширениеза пределами локального блока.

Спасибо.

РЕДАКТИРОВАТЬ:

@ Jeb
Я пытался использовать встроенный код, а не вфункции, и это сработало.
Затем я попытался поместить его в цикл FOR, и это сломало его.
Вызов функции из цикла = работает.
Встроенный цикл - не работает для меня.
Мне сейчас не нужна эта функциональность.Это всего лишь наблюдение.
Спасибо.

@echo off
REM Changed from function call to inline implementation
setlocal EnableDelayedExpansion
cls
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
set LF=^


rem TWO Empty lines are neccessary
set "original=zero*? %%~A%%~B%%~C%%~L!LF!one&line!LF!two with exclam^! !LF!three with "quotes^&"&"!LF!four with ^^^^ ^| ^< ^> ( ) ^& ^^^! ^"!LF!xxxxxwith CR!CR!five !LF!six with ^"^"Q ^"^"L still six "

setlocal DisableDelayedExpansion
SET result=""
REM call :lfTest result original
::::::::::::::::::::
for /L %%i in (1,1,2) do (
setlocal
set "NotDelayedFlag=!"
echo(
if defined NotDelayedFlag (echo lfTest was called with Delayed Expansion DISABLED) else echo lfTest was called with Delayed Expansion ENABLED
setlocal EnableDelayedExpansion
set "var=!original!"

rem echo the input is:
rem echo !var!
echo(

rem ** Prepare for return
set "var=!var:%%=%%~2!"
set "var=!var:"=%%~3!"
for %%a in ("!LF!") do set "var=!var:%%~a=%%~L!"
for %%a in ("!CR!") do set "var=!var:%%~a=%%~4!"

rem ** It is neccessary to use two IF's, else the %var% expansion doesn't work as expected
if not defined NotDelayedFlag set "var=!var:^=^^^^!"
if not defined NotDelayedFlag set "var=%var:!=^^^!%" !

set "replace=%% """ !CR!!CR!"
for %%L in ("!LF!") do (
   for /F "tokens=1,2,3" %%2 in ("!replace!") DO (
     ENDLOCAL
     ENDLOCAL
     set "result=%var%" !
     @echo off
   )
)
)
::::::::::::::::::::
setlocal EnableDelayedExpansion
echo The result with disabled delayed expansion is:
if !original! == !result! (echo OK) ELSE echo !result!

echo ------------------
echo !original!

pause
goto :eof

1 Ответ

2 голосов
/ 23 февраля 2012

Как я уже говорил в вашем другом вопросе: Пакет: возвращение значения из SETLOCAL EnableDelayedExpansion

Просто перейдите по ссылке для «идеального» решения

Или я могу вставить код здесь

rem ** Preparing CR and LF for later use
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
set LF=^


rem TWO Empty lines are neccessary

Затем в начале вашей функции, чтобы определить, установлено ли delayedExpansion в положение OFF или ON

setlocal
set "NotDelayedFlag=!"
setlocal EnableDelayedExpansion

И в конце вашей функции вернуть значение

rem ** Prepare for return
set "var=!var:%%=%%~2!"
set "var=!var:"=%%~3!"
for %%a in ("!LF!") do set "var=!var:%%~a=%%~L!"
for %%a in ("!CR!") do set "var=!var:%%~a=%%~4!"

rem ** It is neccessary to use two IF's, else the %var% expansion doesn't work as expected
if not defined NotDelayedFlag set "var=!var:^=^^^^!"
if not defined NotDelayedFlag set "var=%var:!=^^^!%" !

set "replace=%% """ !CR!!CR!"
for %%L in ("!LF!") do (
   for /F "tokens=1,2,3" %%2 in ("!replace!") DO (
     ENDLOCAL
     ENDLOCAL
     set "%~1=%var%" !
     @echo off
      goto :eof
   )
)

РЕДАКТИРОВАТЬ: немного более короткое изменение
Хорошо, это выглядит немного сложнее, и во многих случаях это можно решить с помощью другого трюка.
Если вы знаете, что вы переключитесь обратно с EnableDelayed на DisableDelayed, и вы уверены, что не используете какой-либо LF, FOR-RETURN будет работать тоже.

@echo off
setlocal
call :myTest result
set result
goto :eof

:myTest
setlocal EnableDelayedExpansion
rem ... do something here
set "value=^!_&_%%_|_>"

echo --
for /f ^"eol^=^

^ delims^=^" %%a in ("!value!") do (
    endlocal
    set "%~1=%%a"
    goto :eof
) 

Разделение for /f ^"eol^=^.... предназначено только для отключения символа eol.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...