简体   繁体   中英

How to use Delayed Variable Expansion to reference a variable from a string

I am trying to create a small script to do light template replacement duties, but I'm getting stuck with dereferencing a variable the way I want.

Here's my template replacement batch file:

@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

an example input file might look like:

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

and an example call might look like:

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

example output I want to see would be:

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

when I get into the ELSE, I get output like:

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

(note: I'm purposefully echoing the replacement situation to the console vs. the file since I'm debugging; that is reflected in the output above).

!replace! is correct; it's the name of a variable I want to expand, so I tried !!replace!!, since I expected !replace! to dump something like comp.name and then !comp.name! would resolve to TestApp (and since I want it resolving at execute time, this feels like the proper syntax to be sniffing at). that is not what happens, however -- instead I just get comp.name, etc. I have now gone through every iteration of replace I can think to try (eg %!replace!%, !!replace!! and nonsensical ones like %%replace%%, !%replace%! and !!!replace!!!) but nothing jives. ECHOing !comp.name! from within the FOR shows that the variable can be resolved (as does %comp.name%) so I'm extremely confused why !!replace!! wouldn't be the proper thing to do here.

is there a trick that I'm missing?

ps while alternate scripts that will solve the problem I'm trying to solve are certainly welcome, I am interested in knowing why I cannot solve it this way.

This type of management is explained at this answer ; for example, you may use anyone of these methods:

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

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

The last line run faster than the former...

This should work with your test file and may help you with your specific issue:

@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%

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM