Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 810 Vote(s) - 3.47 Average
  • 1
  • 2
  • 3
  • 4
  • 5
BAT-file: variable contents as part of another variable

#1
Suppose i have variable **a** with contents "**123**" and variable **b123** with some text in it. For some reason i want to use variable **a** as part of second var name. Something like this:

SET a=123
SET b123=some_text_in_it
rem i want next line to output "some_text_in_it"
echo %b%a%%

so i want to concatenate text with var contents and use resulting string as variable name to echo that contents. Sample above doesn't work and i see why, probably i need to add some kind of groupping. How to do it, prefferably in one line?
Reply

#2
The best reason to "use a variable as part of second var name" is to access array (vector and matrix) elements via a subscript variable. Although this is exactly the same than the example above, it looks much clearer:

setlocal EnableDelayedExpansion
set i=123
set v[123]=Value of element 123
call echo %%v[%i%]%%
echo !v[%i%]!

Although `CALL` is slower than `Delayed Expansion`, as jeb said above, it may be nested several times allowing to use a second (or deeper) indirection to access array elements. This feature may be used in complex data structures, like linked lists. For example:

set i=123
set v[123]=456
set w[456]=Value of element 456
call call echo %%%%w[%%v[%i%]%%]%%%%

**EDIT**: For some reason I don't understand, the Delayed Expansion version of the last command doesn't work properly:

call echo !w[%%v[%i%]%%]!
Reply

#3
There is yet one more way to accomplish the task that is very useful if both variables have been assigned within the same parenthesized block that is expanding them. The solution is similar to jeb's delayed expansion answer, except it uses a FOR variable instead of normal expansion.

@echo off
setlocal enableDelayedExpansion

:: Define a linefeed value - only needed for last variant
set LF=^


:: The two blank lines above are critical to the definition of LF

(
set A=123
set B123=some_text_in_it

rem ECHO !B%A%! will fail because A was assigned within the same block

rem This works as long as A does not contain * or ?
for %%A in ("!A!") do echo !B%%~A!

rem This works as long as A does not start with EOL character (; by default)
for /f "delims=" %%A in ("!A!") do echo !B%%A!

rem This will never fail because it disables EOL by setting it to a linefeed
for /f eol^=^%LF%%LF%^ delims^= %%A in ("!A!") do echo !B%%A!
)

The CALL trick could also be used, but comparatively it is very slow, and it is unreliable - see [CALL me, or better avoid call](

[To see links please register here]

).

The definition and use of a linefeed variable is discussed at

[To see links please register here]

.

Setting EOL to a linefeed is described in detail at [HOW TO: FOR /F Disabling EOL or using a quote as delim](

[To see links please register here]

). Using an LF variable instead of embedding linefeeds within the FOR statement is just an extension of the technique. It makes the code more readable.

***EDIT***<br/>
A simpler way to safely use the FOR technique for any valid value is to set EOL to an equal sign, since no user defined variable can contain an = in the name.

for /f "eol== delims=" %%A in ("!A!") do echo !B%%A!

Reply

#4
There are two common ways for this
`CALL` or `DelayedExpansion`

setlocal EnableDelayedExpansion
SET a=123
SET b123=some_text_in_it
rem i want next line to output "some_text_in_it"
call echo %%b%a%%%
echo !b%a%!

The `CALL` variant uses the fact, that a call will reparse the line a second time, first time only the `%a%` will be expanded and the double `%%` will be reduced to a single `%`
`call echo %b123%`
And in the second step the `%b123%` will be expanded.
But the `CALL` technic is slow and not very safe, so the DelayedExpansion should be prefered.

The DelayedExpansion works as the exclamation marks are expanded in a later parser phase than the expansion of the percents.
And that's also the cause, why delayed expansion is much safer.

**Edit: Method for arrays containing numbers**
If you are operating with arrays which contains only numbers you could also use `set /a` to access them.
That's much easier than the `FOR` or `CALL` technic and it works also in blocks.

setlocal EnableDelayedExpansion
set arr[1]=17
set arr[2]=35
set arr[3]=77
(
set idx=2
set /a val=arr[!idx!]
echo !var!
)
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through