2009-07-29 11 views
11

Korzystanie z wiersza polecenia systemu Windows XP CMD mogę poszerzyć dwukrotnie zmienną w następujący sposób:Jak poszerzyć zmienną powłoki CMD dwukrotnie (rekurencyjnie)

set AAA=BBB 
set BBB=CCC 
for /F "usebackq tokens=*" %i in (`echo %%AAA%%`) do echo %i 

będzie echo CCC. To znaczy. AAA został rozszerzony na ciąg BBB, a następnie zmienna BBB została rozszerzona na CCC.

To nie działa z poziomu skryptu wsadowego (tzn. Pliku .cmd). Zmiana %%AAA%% na %%%AAA%%% lubrównież nie działa.

Każdy pomysł, w jaki sposób mogę to osiągnąć z poziomu skryptu, a mianowicie, aby rozwinąć zmienną AAA do łańcucha znaków CCC?

Późno Edit

Odpowiedzi wysłane pracę dla mojej ograniczonej przykład jednak odpowiedź nie pokrętne nie działa w rzeczywistym przypadku. Oto przykład rozszerzonym (które nie działa), co ilustruje to, czego rzeczywiście próbuje zrobić:

setlocal enabledelayedexpansion 

set LIST=BBB CCC DDD 
set BBB=111 
set CCC=222 
set DDD=333 

for %%i in (%LIST%) do (

    for /F %%a in ('echo %%%i%') do echo !%%a! 

) 

Chciałbym zobaczyć

111 
222 
333 

wyjście.

+0

dinged bo ciebie są nadal w pliku wsadowym i nie używają powłoki powershell. ;) – Cheeso

+1

Nie można używać PowerShell, jeszcze nie co najmniej. –

+0

To nie jest Twoje oświadczenie * Odpowiedzi zamieszczone na stronie działają dla mojego zredukowanego przykładu, jednak niewerkowalna odpowiedź nie działa dla prawdziwego przypadku * w sprzeczności z Twoim komentarzem do postu * akf * * Dzięki, oba z nich rzeczywiście praca.*? –

Odpowiedz

12

Myślenie w kategoriach mniej krętego rozwiązania, to także powoduje, że użytkownik chce uzyskać CCC.

setlocal enabledelayedexpansion 
set AAA=BBB 
set BBB=CCC 
for /F %%a in ('echo %AAA%') do echo !%%a! 

edit:

wnikliwie tej odpowiedzi:

setlocal enabledelayedexpansion - pozwoli to na każdym zmiennym otoczeniu środowiska podczas bat być stosowany jako zmodyfikowane w trakcie swojej pętli for.

set AAA=BBB, set BBB=CCC - Twój populacja dane set oświadczenia

for /F %%a in ('echo %AAA%') do echo !%%a! - Mówi to procesor do pętli, choć tylko raz, i wyjąć pierwszy znak, który jest zwracany (domyślny separator przestrzeni i karcie mają zastosowanie) z uruchomienie polecenia w parens i umieszczenie go w var %% a (poza partią, wystarczy jeden%). Jeśli określisz var jako %% a, musisz użyć %% a w swoim bloku do. Podobnie, jeśli podasz %% i, użyj %% i w swoim bloku do. Zauważ, że aby uzyskać zmienną środowiskową, która ma zostać rozwiązana w bloku do pętli, musisz ją otoczyć w !. (nie musisz w bloku in, jak pierwotnie napisałem - dokonałem tej zmiany w mojej edycji).

edit:

Byliście bardzo blisko ze zaktualizowanym przykład. Spróbuj to tak:

@echo off 
setlocal enabledelayedexpansion 
set LIST=BBB CCC DDD 
set BBB=111 
set CCC=222 
set DDD=333 

for %%i in (%LIST%) do (
    for /F %%a in ('echo %%i') do echo !%%a! 
) 

różnica między aktualizacją i to jest to, że starali się echo zmienną środowiskową w zestawie in z in ('echo %%%i%'), ale bez ! „s opóźnionego ekspansji zestaw zmiennych. Gdybyś użył in ('echo !%%i!'), zobaczyłbyś, że zmienione są twoje zmienne, ale wtedy blok do twojej wewnętrznej pętli nie miałby nic do rozwiązania - nie masz żadnych zmiennych środowiskowych 111. Mając to na uwadze, można uprościć pętlę z następujących czynności:

@echo off 
setlocal enabledelayedexpansion 
set LIST=BBB CCC DDD 
set BBB=111 
set CCC=222 
set DDD=333 

for %%i in (%LIST%) do (echo !%%i!) 
+0

Chociaż jest to rzeczywiście mniej kręty, var, którego faktycznie używam, jest częścią pętli for, np. zamiast AAA mam i: dla %% w (% LIST%) do ( :: użyj i W tym przypadku podstawianie i dla AAA w twoim rozwiązaniu nie działa. Wszelkie pomysły? –

+0

Jestem nie jestem pewien, że podążam za tym, co mówisz. Używając var pętli 'for' w nietoperzu, podwójne% powinno zrobić lewę. Użyłem %% a, który byłby taki sam jak %% i w twoim przykładzie Być może mógłbyś dołączyć bardziej konkretny przykład do tego pytania: – akf

+0

Dodałem kolejny przykład na to pytanie: –

3

Poniższa metoda (torturous) wydaje się działać dobrze:

@echo off 
:main 
    setlocal enableextensions enabledelayedexpansion 
    set aaa=bbb 
    set bbb=ccc 
    call :myset x %%aaa%% 
    echo %x% 
    endlocal 
    goto :eof 
:myset 
    for /F "usebackq tokens=*" %%i in (`echo %%%2%%`) do set %1=%%i 
    goto :eof 

on wyjść:

ccc 

to pożądane.

ja często wykorzystywane tę sztuczkę do formatu %aaa% (na przykład) na %x% do pewnej wielkości (a la sprintf), ale to jest pierwszy raz miałem do zrobienia podwójnego zadnie. Działa, ponieważ nie można znaleźć dodatkowego poziomu, który jest zasysany przez bieżący poziom powłoki.

+0

Które dodatkowe '%%' masz na myśli? –

0

Podwójny dwukierunkowy (który jest bardzo trafny sposób, jak to określił pax) przypomina o odwoływaniu wskaźnika C.
Wątpię, że jest obsługiwany w Windows command shell.

Czy uważasz, że większy cel, na który kierujesz, można osiągnąć dzięki czemuś łatwiejszemu;
może mniejszy od kod-golfa podejście to ten wymyślony ładnie przez pax?

+0

Prawdopodobnie wymagałoby to osobnego pytania, ale w przeciwnym razie obecne odpowiedzi nie będą miały sensu. –

3

Ten aaa.bat

@echo off 
set aaa=bbb 
set bbb=ccc 
for /F %%i in ('echo %%%aaa%%%') do echo %%i 

wyjścia

c:>ccc 

czym dokładnie polega problem?

+0

Jeśli spróbujesz użyć dużych liter dla nazw zmiennych, jak na mój przykład, to nie działa. Otrzymujesz% CCC%. –

+0

@jonh. Wypróbowałem powyższy skrypt w systemie Vista po zmianie 'aaa' na' AAA' i 'bbb' na' BBB', a wyjście to 'ccc'. –

+0

@ Piotr. Używałem XP w tym czasie –

7

Jak poszerzyć powłokę zmienne wielokrotnie:

@echo off 
setlocal enabledelayedexpansion 

set myvar=second 
set second=third 
set third=fourth 
set fourth=fifth 

echo Variable value before expansion: !myvar! 
call :expand myvar 
echo Variable value after expansion: !myvar! 
goto :eof 


:expand 
    set var=%1 
    :expand_loop 
     if not "!%var%!" == "" (
      set var=!%var%! 
      goto :expand_loop 
     ) 
     set %1=!var! 
    goto :eof 

wyjściowa:

Variable value before expansion: second 
Variable value after expansion: fifth 
+1

Kontynuacja: [Dlaczego opóźnienie ekspansji w pliku wsadowym nie działa w tym przypadku?] (Http://stackoverflow.com/questions/7882395/) –

0

wydaje się najprostszym rozwiązaniem jest utworzenie pliku drobny temp ustawić zmienną jak ty życzenie. coś takiego powinno zadziałać:

setlocal enabledelayedexpansion 

set LIST=BBB CCC DDD 
set BBB=111 
set CCC=222 
set DDD=333 

for %%i in (%LIST%) do (
    echo set a=\%%%i\%>tmp.bat 
    call tmp.bat 
    echo %a 
    rm tmp.bat 
) 
1

Jest to nieco przestarzałe pytanie, ale, co ciekawe, odpowiedź jest teraz prostsza.Używam tych skryptów w systemie Windows 10:

setlocal enabledelayedexpansion 
set AAA=BBB 
set BBB=CCC 
echo !%AAA%! 

wyjścia

CCC 

Dla wersji rozszerzonej, to działa:

setlocal enabledelayedexpansion 
set LIST=BBB CCC DDD 
set BBB=111 
set CCC=222 
set DDD=333 
for %%i in (%LIST%) do (
    echo !%%i! 
) 

wyjścia

111 
222 
333 
Powiązane problemy