我正在尝试创建一个小脚本来执行轻量模板替换任务,但是我已经陷入了以我想要的方式解除引用变量的问题。
这是我的模板替换批处理文件:
@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。虽然可以解决我试图解决的问题的替代脚本当然是受欢迎的,我有兴趣知道为什么我不能这样解决它。
答案 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%