如何递归扩展环境变量?
How to recursively expand an environment variable?
假设如下:
echo %MY_ENV_VAR%
扩展为 %USERPROFILE%\some\path
echo %USERPROFILE%
扩展为 C:\Users\MyUser
我的目标是在以下路径创建一个空文件:C:\Users\MyUser\some\path\FOO.txt
.
我尝试了以下命令:type nul > %MY_ENV_VAR%\FOO.txt
不幸的是,输出是一个错误,指出系统找不到指定的路径。
我很确定这是因为 shell 没有递归扩展 %MY_ENV_VAR%
并且它试图找到以 %USERPROFILE%
开头的文字路径。
我怎样才能最好地实现我的目标?
rem Create the problem
set "MY_ENV_VAR=%%USERPROFILE%%\some\path"
echo %MY_ENV_VAR%
rem One solution
call set "MY_ENV_VAR=%MY_ENV_VAR%"
echo %MY_ENV_VAR%
在call
行,解析器会用变量的内容替换%MY_ENV_VAR%
,生成
call set "MY_ENV_VAR=%USERPROFILE%\some\path"
执行此命令时,call
将强制执行第二个解析阶段,生成
set "MY_ENV_VAR=C:\Users\MyUser\some\path"
当然,如果USERPROFILE
包含另一个变量引用,则必须重复该过程。
edited - 添加了 "solution" 到 "recursive" 问题并将所有代码放在子例程中。
@echo off
setlocal enableextensions disabledelayedexpansion
rem Create the problem
set "_1first=c:\users"
set "_2second=%%_1first%%\test"
set "_3third=%%_2second%%\so & me\path"
set "_4fourth=%%_3third%%"
set "MY_ENV_VAR=%%_4fourth%%"
echo inner variables
echo -----------------------------
set _
echo -----------------------------
echo(
echo "MY_ENV_VAR = [%MY_ENV_VAR%]"
call :expandInnerVariables MY_ENV_VAR
echo "MY_ENV_VAR = [%MY_ENV_VAR%]"
goto :eof
:expandInnerVariables varName
setlocal enableextensions disabledelayedexpansion
set "aux=="
for /l %%i in (0 1 100) do (
setlocal enabledelayedexpansion
if "!%~1!"=="" (
endlocal & goto :endExpand
) else for /f "delims=" %%a in ("=!%~1!") do (
endlocal & call set "%~1%%a"
setlocal enabledelayedexpansion
for /f "delims=" %%b in ("=!%~1!") do (
endlocal & set "aux=%%b" & if %%a==%%b goto :endExpand
)
)
)
:endExpand
endlocal & set "%~1%aux%"
goto :eof
假设如下:
echo %MY_ENV_VAR%
扩展为 %USERPROFILE%\some\path
echo %USERPROFILE%
扩展为 C:\Users\MyUser
我的目标是在以下路径创建一个空文件:C:\Users\MyUser\some\path\FOO.txt
.
我尝试了以下命令:type nul > %MY_ENV_VAR%\FOO.txt
不幸的是,输出是一个错误,指出系统找不到指定的路径。
我很确定这是因为 shell 没有递归扩展 %MY_ENV_VAR%
并且它试图找到以 %USERPROFILE%
开头的文字路径。
我怎样才能最好地实现我的目标?
rem Create the problem
set "MY_ENV_VAR=%%USERPROFILE%%\some\path"
echo %MY_ENV_VAR%
rem One solution
call set "MY_ENV_VAR=%MY_ENV_VAR%"
echo %MY_ENV_VAR%
在call
行,解析器会用变量的内容替换%MY_ENV_VAR%
,生成
call set "MY_ENV_VAR=%USERPROFILE%\some\path"
执行此命令时,call
将强制执行第二个解析阶段,生成
set "MY_ENV_VAR=C:\Users\MyUser\some\path"
当然,如果USERPROFILE
包含另一个变量引用,则必须重复该过程。
edited - 添加了 "solution" 到 "recursive" 问题并将所有代码放在子例程中。
@echo off
setlocal enableextensions disabledelayedexpansion
rem Create the problem
set "_1first=c:\users"
set "_2second=%%_1first%%\test"
set "_3third=%%_2second%%\so & me\path"
set "_4fourth=%%_3third%%"
set "MY_ENV_VAR=%%_4fourth%%"
echo inner variables
echo -----------------------------
set _
echo -----------------------------
echo(
echo "MY_ENV_VAR = [%MY_ENV_VAR%]"
call :expandInnerVariables MY_ENV_VAR
echo "MY_ENV_VAR = [%MY_ENV_VAR%]"
goto :eof
:expandInnerVariables varName
setlocal enableextensions disabledelayedexpansion
set "aux=="
for /l %%i in (0 1 100) do (
setlocal enabledelayedexpansion
if "!%~1!"=="" (
endlocal & goto :endExpand
) else for /f "delims=" %%a in ("=!%~1!") do (
endlocal & call set "%~1%%a"
setlocal enabledelayedexpansion
for /f "delims=" %%b in ("=!%~1!") do (
endlocal & set "aux=%%b" & if %%a==%%b goto :endExpand
)
)
)
:endExpand
endlocal & set "%~1%aux%"
goto :eof