2015-04-20 4 views
2

Предположим следующее:Как рекурсивно расширить переменную окружения?

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

К сожалению, выход есть ошибка, которая заявляет Система не может найти указанный путь.

Я довольно уверен, что это происходит потому, что оболочка не рекурсивно расширяется %MY_ENV_VAR% и он пытается найти буквальный путь, который начинается с %USERPROFILE%.

Как я могу достичь цели?

+0

Что дает вам 'echo% MY_ENV_VAR%'? – nneonneo

+0

@nneonneo '% USERPROFILE% \ some \ path', а выход' echo% USERPROFILE% 'расширяется до' C: \ Users \ MyUser' – SiegeX

+0

Обычно Windows будет делать это для вас при настройке блока среды. Возможно, релевантно: http://stackoverflow.com/questions/13183575/m2-not-working-in-system-variable-path-but-in-user-variable-path-only http://superuser.com/questions/ 823190/are-there-rules-to-windows-7-variable-variable-names –

ответ

3
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 содержит другую ссылку на переменную, процесс должен быть повторяется.

отредактировал - Добавлено «решение» для «рекурсивной» проблемы и поместило весь код внутри подпрограммы.

@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 
+0

Если вы можете обобщить его, обернув часть 'call set ...' в цикле, которая выполняется, в то время как выход по-прежнему содержит шаблон, соответствующий регулярному выражению '% [^%] +%', я обязательно отмечу это как решение. Примечание: вам не нужно использовать регулярное выражение, это всего лишь способ получить мою точку зрения; Я не уверен, что пакетные файлы даже поддерживают регулярное выражение. – SiegeX

+0

Я только что нашел [следующий сайт] (http://ss64.com/nt/call.html#advanced), который делает что-то подобное с 'CALL set ', но в конце он рекомендует использовать замедленное расширение вместо' CALL 'будучи очень медленным в цикле, когда он пытается получить доступ к диску. Я попытался получить отсроченное расширение для работы, но, похоже, не понял его. Если вы можете получить for-loop, который будет расширять N-вложенную переменную, используя задержанное расширение, которое было бы чрезвычайно оценено. – SiegeX

+0

@SiegeX, ответ обновлен. –

Смежные вопросы