|
Answer» I think this is do-able, I just don't know the syntax...
First, the basics: Code: [Select]@ECHO OFF CLS ; VERIFY OTHER 2>NUL SETLOCAL ENABLEEXTENSIONS IF ERRORLEVEL 1 ( ECHO Cannot enable COMMAND Extensions GOTO EndError ) ; VERIFY OTHER 2>NUL SETLOCAL ENABLEDELAYEDEXPANSION IF ERRORLEVEL 1 ( ECHO Cannot enable Delayed Environment Variable Expansion GOTO EndError ) Now set a few variables: Code: [Select]IF NOT DEFINED TEST SET TEST=C:\Temp IF NOT DEFINED Test1 SET Test1=%TEST%\Test123 IF NOT DEFINED TestABC SET TestABC=%TEST%\TestXYZ IF NOT DEFINED TestFoo SET TestFoo=%TEST%\TestFoo IF NOT DEFINED TestBad SET TestBad=%TEST%\NoSuchThing See what's what: Code: [Select]ECHO. ECHO TEST = %TEST% ECHO Test1 = %Test1% ECHO TestABC = %TestABC% ECHO TestFoo = %TestFoo% ECHO TestBad = %TestBad% ECHO. What I get: TEST = C:\Temp Test1 = C:\Temp\Test123 TestABC = C:\Temp\TestXYZ TestFoo = C:\Temp\TestFoo TestBad = C:\Temp\NoSuchThing
What I'm trying to do here is nest the arguments. In other words, I want an argument1 to EXPAND to the NAME of argument2, which in turn should expand to the VALUE of argument2. Example: Code: [Select]FOR %%d IN (Test1 TestABC TestFoo TestBad) DO ( SET ThisArg=%%d ECHO ThisArg = !ThisArg!
SET ThisArgValue=UNKNOWN ECHO ThisArgValue = !ThisArgValue! )
What I get: ThisArg = Test1 ThisArgValue = UNKNOWN
ThisArg = TestABC ThisArgValue = UNKNOWN
ThisArg = TestFoo ThisArgValue = UNKNOWN
ThisArg = TestBad ThisArgValue = UNKNOWN
What I WANT: ThisArg = Test1 ThisArgValue = C:\Temp\Test123
ThisArg = TestABC ThisArgValue = C:\Temp\TestXYZ
ThisArg = TestFoo ThisArgValue = C:\Temp\TestFoo
ThisArg = TestBad ThisArgValue = C:\Temp\NoSuchThing
See it? On the first iteration, %%d resolves to the string value Test1.
I want ThisArgValue to resolve to !Test1! -- in other words, the VALUE of %%d, not the "name" or "string" of %%d.
In turn, !ThisArgValue! (note the !difference!) should resolve to %TEST%\Test1 == C:\Temp\Test1.
Intuitively, the expansion I'm looking for would be written as: %(%%d)%
or
!(%%d)!
using Delayed Expansion... but that syntax doesn't work. Neither does any combination of ~tilde, (parenthesis), [brackets] or !%bookends%! I've tried.
Help??? Many thanks. The solution involves CALL and double percent signs.
Modifying your code slightly, (but also see below***)
I only show the LOOP, since the rest is identical to your code which you posted above.
Code: [Select]FOR %%d IN (Test1 TestABC TestFoo TestBad) DO ( set thisarg=%%d ECHO ThisArg = !ThisArg! REM Note (1) CALL REM Note (2) Percent signs.. REM Note (3) ...Doubled up call SET ThisArgValue=%%!Thisarg!%% ECHO ThisArgValue = !ThisArgValue! echo. ) Output
Code: [Select]TEST = C:\Temp Test1 = C:\Temp\Test123 TestABC = C:\Temp\TestXYZ TestFoo = C:\Temp\TestFoo TestBad = C:\Temp\NoSuchThing
ThisArg = Test1 ThisArgValue = C:\Temp\Test123
ThisArg = TestABC ThisArgValue = C:\Temp\TestXYZ
ThisArg = TestFoo ThisArgValue = C:\Temp\TestFoo
ThisArg = TestBad ThisArgValue = C:\Temp\NoSuchThing *** see here
Quote Intuitively, the expansion I'm looking for would be written as: %(%%d)%
... You're nearly there! Just use CALL and double up the percents as in this alternative to above loop:
Code: [Select]FOR %%d IN (Test1 TestABC TestFoo TestBad) DO ( set thisarg=%%d call set thisargvalue=%%%%d%% ECHO ThisArg = !ThisArg! ECHO ThisArgValue = !ThisArgValue! echo. )
To be echoed or otherwise invoked, percent signs, being special characters, need 'escaping'; the escape character is... another percent sign, then you use call (or CALL as you seem to prefer) to pass the command to a child cmd thus %%variablename%% becomes %variablename% which is expanded to the variable's value.
You did know that it is not OBLIGATORY to write batch code in ALL UPPER CASE? (Just a stylistic preference I guess)
Yeah, the CAPS are just for style. CALL SET makes perfect sense. OUTSTANDING! Many thanks!!!
|