setlocals批次之间的变量preserving惊叹号 [英] preserving exclamation marks in variable between setlocals batch

查看:193
本文介绍了setlocals批次之间的变量preserving惊叹号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

试图preserve感叹号变量。一个简化的,说明如下脚本:

Trying to preserve exclamation marks in variables. A simplified, illustrative script below:

    echo off
    set testvar="C:\Windows\TestOfIllegals[!]"
    echo Pre-EnableDE: %testvar%

    setlocal enableextensions enabledelayedexpansion
    echo Post-EnableDE: %testvar%

    Setlocal DisableDelayedExpansion
    echo ssetlocal sub-instance...
    echo TestVar after re-disableDE: %testvar%
    set modTestVar=%testvar%
    echo TestVar to new var, modTestVar: %modTestVar%
    endlocal & set "RetVar2=%modTestVar%"

    echo modTestVar back in main script: %RetVar2%

    Setlocal DisableDelayedExpansion
    echo modTestVar, main script in another setlocal diasbleDE instance: %RetVar2%
    endlocal

    pause
    exit /b

这将产生输出:

    Pre-EnableDE: "C:\Windows\TestOfIllegals[!]"
    Post-EnableDE: "C:\Windows\TestOfIllegals[]"
    ssetlocal sub-instance...
    TestVar after re-disableDE: "C:\Windows\TestOfIllegals[!]"
    TestVar to new var, modTestVar: "C:\Windows\TestOfIllegals[!]"
    modTestVar back in main script: "C:\Windows\TestOfIllegals[]"
    modTestVar, main script in another setlocal diasbleDE instance: "C:\Windows\TestOfIllegals[]"

在modTestVar为什么没有感叹号是preserved?有没有办法做到这一点?

Why isn't the exclamation mark being preserved in modTestVar? Is there any way to do this?

(我知道发布完整的脚本以前人说 - 但相当长的,这再presents的核心问题然而,乐于如果有帮助的POST)。

(I know people have said before "post the full script" - but rather long and this represents the core issue. However, happy to post if helpful).

感谢

推荐答案

这是在变量preserved,但你需要使用延迟扩展。

It's preserved in the variable, but you need to use delayed expansion.

当您使用延迟扩展模式百分号展开变量将扩大和内容,特别是感叹号将被解析会后来也被解析,和一个感叹号就干脆删除。

When you used percent expansion in delayed expansion mode the variable will be expanded and the content, especially the exclamation marks will be parsed will be parsed also later, and a single exclamation mark will simply removed.

echo off
set testvar="C:\Windows\TestOfIllegals[!]"
echo Pre-EnableDE: %testvar%

setlocal enableextensions enabledelayedexpansion
echo Post-EnableDE: !testvar!

Setlocal DisableDelayedExpansion
echo ssetlocal sub-instance...
echo TestVar after re-disableDE: %testvar%
set modTestVar=%testvar%
echo TestVar to new var, modTestVar: %modTestVar%
endlocal & set "RetVar2=%modTestVar%"

echo modTestVar back in main script: !RetVar2!

Setlocal DisableDelayedExpansion
echo modTestVar, main script in another setlocal diasbleDE instance: %RetVar2%
endlocal

pause

另外/唯一的问题是,当你试图将一个变量通过一个ENDLOCAL层上传输(如 ENDLOCAL和放大器;设置RetVar2 =%modTestVar%

这就是不平凡

这是此批宏,这样使用
%ENDLOCAL%modTestVar

This is a batch macro for this, used like this %endlocal% modTestVar

setlocal DisableDelayedExpansion
set LF=^


set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
%=   I use EDE for EnableDelayeExpansion and DDE for DisableDelayedExpansion =%
set ^"endlocal=for %%# in (1 2) do if %%#==2 (%\n%
   setlocal EnableDelayedExpansion%\n%
 %=       Take all variable names into the varName array       =%%\n%
   set varName_count=0%\n%
   for %%C in (!args!) do set "varName[!varName_count!]=%%~C" ^& set /a varName_count+=1%\n%
 %= Build one variable with a list of set statements for each variable delimited by newlines =%%\n%
 %= The lists looks like --> set result1=myContent\n"set result1=myContent1"\nset result2=content2\nset result2=content2\n     =%%\n%
 %= Each result exists two times, the first for the case returning to DDE, the second for EDE =%%\n%
 %= The correct line will be detected by the (missing) enclosing quotes  =%%\n%
   set "retContent=1!LF!"%\n%
   for /L %%n in (0 1 !varName_count!) do (%\n%
      for /F "delims=" %%C in ("!varName[%%n]!") DO (%\n%
         set "content=!%%C!"%\n%
         set "retContent=!retContent!"set !varName[%%n]!=!content!"!LF!"%\n%
         if defined content (%\n%
 %=      This complex block is only for replacing '!' with '^!'      =%%\n%
 %=    First replacing   '"'->'""q'   '^'->'^^' =%%\n%
         set ^"content_EDE=!content:"=""q!"%\n%
         set "content_EDE=!content_EDE:^=^^!"%\n%
 %= Now it's poosible to use CALL SET and replace '!'->'""e!' =%%\n%
         call set "content_EDE=%%content_EDE:^!=""e^!%%"%\n%
         %= Now it's possible to replace '""e' to '^', this is effectivly '!' -> '^!'  =%%\n%
         set "content_EDE=!content_EDE:""e=^!"%\n%
         %= Now restore the quotes  =%%\n%
         set ^"content_EDE=!content_EDE:""q="!"%\n%
         ) ELSE set "content_EDE="%\n%
         set "retContent=!retContent!set "!varName[%%n]!=!content_EDE!"!LF!"%\n%
      )%\n%
   )%\n%
 %= Now return all variables from retContent over the barrier =%%\n%
   for /F "delims=" %%V in ("!retContent!") DO (%\n%
 %= Only the first line can contain a single 1 =%%\n%
      if "%%V"=="1" (%\n%
 %= We need to call endlocal twice, as there is one more setlocal in the macro itself =%%\n%
         endlocal%\n%
         endlocal%\n%
      ) ELSE (%\n%
 %= This is true in EDE             =%%\n%
         if "!"=="" (%\n%
            if %%V==%%~V (%\n%
               %%V !%\n%
            )%\n%
         ) ELSE IF not %%V==%%~V (%\n%
            %%~V%\n%
         )%\n%
      )%\n%
   )%\n%
 ) else set args="

这篇关于setlocals批次之间的变量preserving惊叹号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆