Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   двойное раскрытие (http://forum.oszone.net/showthread.php?t=237245)

CyberMuesli 24-06-2012 21:51 1939840

двойное раскрытие
 
В переменной VName содержится имя другой переменной окружения. Чтобы получить значение переменной, чье имя содержится в переменной VName, можно использовать такой синтаксис:

set VNAME=FARHOME & rem Но мы этого не знаем
...
set VValue=!%VNAME%!


Как быть, если последнюю строчку надо написать в цикле, в котором %VARNAME% раскроется всего один раз перед циклом. По идее нужно что-то типа такого

Как быть, если последнюю строчку надо написать в цикле или внутри IF, где %VARNAME% раскроется всего один раз перед скобками. По идее нужно что-то типа такого

set VValue=!!VNAME!!

Но так не работает. Как быть?

Iska 24-06-2012 22:09 1939847

Где сам пример цикла?

Подобное пробовали?
Код:

@echo off
setlocal enableextensions enabledelayedexpansion

set sValue=Some value
set sVarName=sValue

echo !%sVarName%!
call echo %%%sVarName%%%

endlocal
exit /b 0


CyberMuesli 24-06-2012 22:29 1939854

Цитата:

Цитата Iska
Где сам пример цикла? »

чуть позже. пока я тренировался, у меня перестало работать даже вне цикла. Что тут не так?

upd: в данном примере все работает, просто & echo надо писать на новой строчке


Код:

@echo off

setlocal enabledelayedexpansion

call :vtest MyArray
goto :eof

:vTest

set %1.1=value1
set %1.2=value2
set %1.3=value3

set %1.Index=1

set VNAME=%1.!%1.Index!  & echo VNAME=!VNAME!
set VNAME=!%VNAME%!      & echo VNAME=!VNAME!


Foreigner 24-06-2012 22:41 1939860

Цитата:

Цитата CyberMuesli
set %1.Index=1 »

Код:

set "Index=1"
set "VNAME=!%1.%Index%!"
echo %VNAME%


CyberMuesli 24-06-2012 22:50 1939864

Цитата:

Цитата Foreigner
Код: »

да спасибо, так сработает, но это нарушает условия задачи
в переменной VNAME хранится ИМЯ. В вашем примере оно не хранится, в VNAME сразу попадает нужное значение.
Хотелось бы понять, почему не работает мой пример

Foreigner 24-06-2012 23:14 1939872

CyberMuesli,
C промежуточной переменной работает:
Код:

set "%1.Index=1"
set "Index=!%1.Index!"
echo !%1.%Index%!


CyberMuesli 24-06-2012 23:16 1939875

Цитата:

Цитата Foreigner
C промежуточной переменной работает: »

вы тоже нарушили условия задачи. у вас нет переменной, в которой хранится имя другой переменной

Foreigner 24-06-2012 23:32 1939881

Тогда только как говорил Iska, через "call"
Код:

set %1.Index=1

call set "VNAME=%%%1.!%1.Index!%%"
echo %VNAME%


CyberMuesli 24-06-2012 23:33 1939882

Цитата:

Цитата Iska
Где сам пример цикла? »

Итак, поясняющий пример. Вместо цикла тут IF (видимо закавыка в том, что скобки, как и в цикле). Первый вариант работает, второй нет.

Код:

@echo off

setlocal enabledelayedexpansion

call :vtest MyArray
goto :eof

:vTest
set %1.1=value1
set %1.2=value2
set %1.3=value3

set %1.Count=1

  echo Ok:
  set VNAME=%1.!%1.Count!
  echo VNAME=!VNAME!
  set VNAME=!%VNAME%!
  echo VNAME=!VNAME!

if defined %1.!%1.Count! (
  echo does not working
  set VNAME=%1.!%1.Count!
  echo VNAME=!VNAME!
  set VNAME=!%VNAME%!
  echo VNAME=!VNAME!
)


Foreigner 24-06-2012 23:54 1939894

Код:

if defined %1.!%1.Count! (
  echo does not working
  call set VNAME=%%%1.!%1.Count!%%
  echo VNAME=!VNAME!
  set VNAME=%VNAME%
  echo VNAME=!VNAME!
)


CyberMuesli 24-06-2012 23:56 1939898

Цитата:

Цитата Foreigner
Код:

if defined %1.!%1.Count! (
 echo does not working
 call set VNAME=%%%1.!%1.Count!%%
 echo VNAME=!VNAME!
 set VNAME=%VNAME%
 echo VNAME=!VNAME!
)

»

этот код не работает

Foreigner 24-06-2012 23:59 1939899

Цитата:

Цитата CyberMuesli
этот код не работает »

А что должно быть в итоге? У меня такой вывод:
Цитата:

Ok:
VNAME=MyArray.1
VNAME=value1
does not working
VNAME=value1
VNAME=value1

CyberMuesli 25-06-2012 00:02 1939902

Цитата:

Цитата Foreigner
А что должно быть в итоге? У меня такой вывод: »

Условие: в VNAME должно быть имя другой переменной. В нашем случае это MyArray.1

Код:
Код:

@echo off

setlocal enabledelayedexpansion

call :vtest MyArray
goto :eof

:vTest
set %1.1=value1
set %1.2=value2
set %1.3=value3

set %1.Count=1

  echo Ok:
  set VNAME=%1.!%1.Count!
  echo VNAME=!VNAME!
  set VNAME=!%VNAME%!
  echo VNAME=!VNAME!

if defined %1.!%1.Count! (
  echo does not working
  set VNAME=%1.!%1.Count!
  echo VNAME=!VNAME!
  set VNAME=!%VNAME%!
  echo VNAME=!VNAME!
)


if defined %1.!%1.Count! (
  echo does not working 2
  call set VNAME=%%%1.!%1.Count!%%
  echo VNAME=!VNAME!
  set VNAME=%VNAME%
  echo VNAME=!VNAME!
)

Результаты:
C>Test.bat
Ok:
VNAME=MyArray.1
VNAME=value1
does not working
VNAME=MyArray.1
VNAME=
does not working 2
VNAME=value1
VNAME=

Foreigner 25-06-2012 00:07 1939905

Код:

if defined %1.!%1.Count! (
  echo does not working
  set VNAME=%1.!%1.Count!
  echo VNAME=!VNAME!
  set VNAME=%VNAME%
  echo VNAME=!VNAME!
)

Результат:
Цитата:

Ok:
VNAME=MyArray.1
VNAME=value1
does not working
VNAME=MyArray.1
VNAME=value1

CyberMuesli 25-06-2012 00:09 1939906

Цитата:

Цитата Foreigner
does not working
VNAME=MyArray.1
VNAME=value1 »

работает, но не понимаю, почему) бред какой-то. это не должно работать, тут на одно раскрытие меньше

Нет. Не работает. Ваш код каким-то волшебным образом пользуется значением, которое было вычислено ранее. В общем-то сразу кидалось в глаза, что строчка set VNAME=%VNAME% не должна делать ровным счетом ничего. Это нуль-код, который ничего не меняет.

Пора наверное спать. Все странности с Invalid value понял. В скобки вместо %VARNAME% подставляется то, что было на момент входа в скобки. Так как VNAME уже было правильно вычислено вне скобок, то set VNAME=%VNAME% дает внутри скобок нужный результат, который мы ошибочно интерпретируем как рабочий вариант.

Как вычислить то, что нужно, по прежнему, непонятно.

Привожу канонический проблемный код. В ветку с IF (в выделенную жирным строчку) надо что-то вставить, что дважды раскроет VNAME, так же, как вне скобок

Код:

@echo off

setlocal enabledelayedexpansion

call :vtest MyArray
goto :eof


:vTest

set %1.1=Right value 1
set %1.Index=1

set %1

echo --- Outside brackets is Ok:
set VNAME=%1.!%1.Index!
echo VNAME=!VNAME!
set VNAME=!%VNAME%!
echo VNAME=!VNAME!

echo ---
set VNAME=Invalid value
set VNAME

if defined %1.!%1.Index! (
  echo --- Inside brackets does not working
  set VNAME=%1.!%1.Index!
  set VNAME
  set VNAME=!%VNAME%!
  set VNAME
)


goto :eof


CyberMuesli 25-06-2012 03:02 1939967

Всё. Решение найдено. Для двойного раскрытия надо делать так


for %%i in (!VNAME!) do set VNAME=!%%i!

Всем спасибо.

Iska 25-06-2012 03:50 1939973

Цитата:

Цитата CyberMuesli
Привожу … проблемный код. »

С этого нужно было начинать в первом же посте.

CyberMuesli 25-06-2012 03:53 1939974

Цитата:

Цитата Iska
С этого нужно было начинать в первом же посте. »

я с этого и начал

Цитата:

Цитата CyberMuesli
Цитата Iska:
Где сам пример цикла? »
Итак, поясняющий пример. »


Iska 25-06-2012 06:20 1939984

Ключевые слова — «с этого» и «в первом же».

Foreigner 25-06-2012 06:50 1939986

Цитата:

Цитата CyberMuesli
Нет. Не работает. »

Цитата:

надо что-то вставить, что дважды раскроет VNAME, так же, как вне скобок
Код:

if defined %1.!%1.Count! (

  set VNAME=%1.!%1.Count!
  echo VNAME=!VNAME!
  call set VNAME=%%!VNAME!%%
  echo VNAME=!VNAME!

)


CyberMuesli 25-06-2012 12:27 1940122

Цитата:

Цитата Foreigner
if defined %1.!%1.Count! (
set VNAME=%1.!%1.Count!
echo VNAME=!VNAME!
call set VNAME=%%!VNAME!%%
echo VNAME=!VNAME!
) »

А так не работает.

MyArray.1=Right value 1
MyArray.Index=1
--- Outside brackets is Ok:
VNAME=MyArray.1
VNAME=Right value 1
---
VNAME=Invalid value
--- Inside brackets does not working
VNAME=MyArray.1
VNAME=%MyArray.1%

Цитата:

Цитата Iska
Ключевые слова — «с этого» и «в первом же». »

не вижу проблемы в том. чтобы привести поясняющий пример в ответ на вопрос

PATRI0T 29-12-2020 03:07 2944495

Цитата:

Цитата CyberMuesli
Всё. Решение найдено. Для двойного раскрытия надо делать так
for %%i in (!VNAME!) do set VNAME=!%%i! »

А у меня не работает ((
Вот батник, который берет адрес рабочего стола из реестра, кладет его в DesktopPath (там получается конструкция вида "%USERPROFILE%\Desktop")
И все что я хочу, это переместить один файл по адресу из этой переменной, но не работает двойное раскрытие..

Код:

:: Установка portable версии в нужную папку
@echo on >nul
    cls
    setlocal enabledelayedexpansion       
    chcp 866 >nul 

:: INIT
    set InstallPath=%USERPROFILE%\UserSoft
        mkdir %InstallPath% >nul

:: путь к рабочему столу
    FOR /F "skip=2 tokens=2,*" %%A IN ('reg.exe query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v "Desktop"') DO set "DesktopPath=%%B"
    FOR %%i in (!DesktopPath!) do set DesktopPath=!%%i!
               
    move OperaPortable\OperaMy.lnk %DesktopPath%
    REM move /y OperaPortable %InstallPath%\

Фотодоказательство

PATRI0T 29-12-2020 03:30 2944496

А, все, нашел решение.
Надо просто сделать так
Код:

call set DesktopPath=%DesktopPath%
И усё.. Пошел я спать.. )

Iska 29-12-2020 21:39 2944564

Цитата:

Цитата PATRI0T
Надо просто сделать так »

PATRI0T, вот здесь call как раз не нужен.


Время: 15:06.

Время: 15:06.
© OSzone.net 2001-