如何使用延迟变量扩展来引用字符串中的变量

时间:2016-10-17 22:52:03

标签: windows batch-file cmd

我正在尝试创建一个小脚本来执行轻量模板替换任务,但是我已经陷入了以我想要的方式解除引用变量的问题。

这是我的模板替换批处理文件:

@echo off

echo ------------
echo %~nx0%

SETLOCAL ENABLEDELAYEDEXPANSION

SET "src=%~1"
SET "dst=%~2"

ECHO %src%
FOR /F "tokens=1,2* delims=%%" %%i IN (%src%) DO (

   IF "%%k"=="" (
      ECHO %%i >> %dst%
   ) ELSE (
      SET "first=%%i"
      SET "middle=%%j"
      SET "last=%%k"
      SET "replace=!middle:~2,-1!"

      IF NOT "!first:~-1!"=="<" (
         ECHO %%i >> %dst%
      ) ELSE IF NOT "!middle:~0,1!"=="=" (
         ECHO %%i >> %dst%
      ) ELSE IF NOT "!last:~0,1!"==">" (
         ECHO %%i >> %dst%
      ) ELSE (
         ECHO !first:~0,-1! ^<^< !replace! ^>^> !last:~1!
      )
   )
)

ENDLOCAL

GOTO :EOF

:Error
EXIT /B 1

示例输入文件可能如下所示:

{
    "name":                     "<%= comp.name %>",
    "version":                  "<%= comp.version %>",
    "description":              "<%= comp.description %>",
    "author":                   "me",
    "url":                      "https://localhost/<%= comp.name %>"
}

示例调用可能如下所示:

SET comp.name=TestApp
SET comp.version=1.0
SET comp.description=The most awesome thing you will ever see
CALL TemplateReplacement.bat %1 %2

我希望看到的示例输出是:

{
    "name":                     "TestApp",
    "version":                  "1.0",
    "description":              "The most awesome thing you will ever see",
    "author":                   "me",
    "url":                      "https://localhost/TestApp"
}

当我进入ELSE时,输出如下:

    "name":                     " << comp.name >> ",
    "version":                  " << comp.version >> ",
    "description":              " << comp.description >> ",

(注意:由于我正在调试,我故意回应控制台与文件的替换情况;这反映在上面的输出中。)

!替换!是正确的;它是我想要扩展的变量的名称,所以我试过!!替换!!,因为我的预期!替换!转储类似comp.name然后!comp.name的东西!将解析为TestApp(因为我希望它在执行时解析,这感觉就像正在嗅探的正确语法)。然而,这不是发生的事情 - 相反,我只是得到comp.name等。我现在经历了每次迭代的替换,我可以考虑尝试(例如%!replace!%,!!替换!!和无意义的那些像%%替换%%,!%替换%!和!!!替换!!!)但没有什么可以生效。 ECHOing!comp.name!从FOR中可以看出变量可以被解析(%comp.name%也是如此)所以我非常困惑为什么!!替换!!在这里做的不合适。

有一个我不知道的伎俩吗?

P.S。虽然可以解决我试图解决的问题的替代脚本当然是受欢迎的,我有兴趣知道为什么我不能这样解决它。

2 个答案:

答案 0 :(得分:2)

此类管理在this answer解释;例如,您可以使用以下任何一种方法:

CALL SET replace=%%!middle:~2,-1!%%

FOR /F %%a IN ("!middle:~2,-1!") DO SET replace=!%%a!

最后一行的运行速度比前者快......

答案 1 :(得分:0)

这应该适用于您的测试文件,可能会帮助您解决特定问题:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

SET SRC=%~1
SET DST=%~2

(FOR /F "TOKENS=1,2* DELIMS=<>" %%A IN ('FINDSTR/R "%%.*%%" "%SRC%"') DO (
    SET PRE=%%B
    CALL ECHO=%%A%%!PRE:~3,-2!%%%%C))>%DST%