Imagine a script called batch.bat, invoked like this:
batch.bat Two
The script contains:
set One=1
set Two=2
set Three=3
set Choice=%1
echo %Choice%
But I want to echo 2, not Two.
What elegant way can I employ to do that? I thought about if %Choice%=One, etc. but my actual script is a bit more complex than the example provided.
Edit: I also tried:
set percent=%%
echo %percent%%Choice%%percent%
But it won't treat the resulting expression as a variable reference.
#echo off
setlocal EnableDelayedExpansion
set one=1
set c=%1
echo delayed expansion and variable: !%c%!
echo delayed expansion and paramr: !%1!
call echo using call and variable: %%%c%%%
call echo using call and param: %%%1%%
I personally prefer the delayed expansion method, but sometimes there are reasons to look for an alternative.
OK, I have figured it out:
The key is to use the "set delayed expansion" trick.
There's also a trick using the "call set" instead of the above but I reckon if I use that, the next guy after me won't know what I was trying to do and might get in trouble.
The script can be fixed by adding !! around the reference that we want to force into the variable name, like so:
#echo off
setlocal EnableDelayedExpansion
set One=1
set Two=2
set Three=3
set Choice=!%1!
echo %Choice%
Related
I´m trying to use a variable instead of a fixed number here:
set PACK_VERSION=Testing12345
set PACK_VERSION=%PACK_VERSION:~7,100%
echo %PACK_VERSION%
Instead of this number 7, I would like to use a variable, something like this:
set VARNUM=7
set PACK_VERSION=Testing12345
set PACK_VERSION=%PACK_VERSION:~%VARNUM%,100%
echo %PACK_VERSION%
I don´t know how to insert that properly, anyone can help? Thanks!
The "usual" way is using delayed expansion:
setlocal enabledelayedexpansion
set VARNUM=7
set PACK_VERSION=Testing12345
set PACK_VERSION=!PACK_VERSION:~%VARNUM%!
echo %PACK_VERSION%
but there is also a little trick to do it without delayed expansion (you have to parse the line twice, call is a good method to do so):
set VARNUM=7
set PACK_VERSION=Testing12345
call set PACK_VERSION=%%PACK_VERSION:~%VARNUM%%%
echo %PACK_VERSION%
I wanted the user insert a variable and then be displayed with echo It would be something like %%var%%
A variable inside another variable
set var=value
set x=var
setlocal enableDelayedExpansion
echo !%x%!
...
endlocal
This should outperfrom the call approach.
I hope I got your question right. You need an additional parse-phase. this can be done with call:
set var=value
set x=var
call echo %%%x%%%
REM on commandline: call echo %%x%%
(yes, that's ugly, but it works)
I want to get dir=%dir:~-here% a var.
I find out that this dir=%dir:~-%var%% unfortunaly this doesn`t work.
then I tried :
set var=2
echo dir=%%dir:~-%var%%% > file.txt
for /f "tokens=* delims=" %%a in (file.txt) do set dir=%%a
but then is dir for real %dir:~-2%. If anybody understands my, am I asking you is there a way to do it??
THNX
#echo off
setlocal enabledelayedexpansion
set "var=-2"
echo !cd:~%var%!
To use a variable inside a variable substring operation, the easiest way is to use delayed expansion
If you want to expand variables in a line two times, you need to use Delayed Expansion:
setlocal EnableDelayedExpansion
set var=2
echo dir=!dir:~-%var%! > file.txt
The first expansion happen at %var%, the second (delayed) expansion happen at !dir:~-2!.
EDIT: Another possible way is use the call command that causes that the line be parsed again:
set var=2
call echo dir=%%dir:~-%var%%% > file.txt
When the line is parsed the first time, the first expansion is performed:
call echo dir=%dir:~-2% > file.txt
The call command causes that the line be parsed again and get the final result.
Here is another way to do it with your example.
Using call this way causes an issue with ^ characters and is relatively slower than delayed expansion.
#echo off
set dir=aaabbbccc
set var=3
>file.txt call echo dir=%%dir:~-%var%%%
pause
I'm trying to get to the value of a variable that's made up of two other variables. The only way I've gotten this to work is by using the FOR command with the /F switch and opening a second command shell:
SET A=This
SET B=That
SET ThisThat=YES!
FOR /F %I IN ('ECHO %A%%B%') DO cmd.exe /C ECHO %%I%
Output:
C:\>cmd.exe /c echo %ThisThat%
YES!
Does anyone know of a more elegant way to do this?
UPDATE
Here's a better explanation of what I was trying to accomplish (and was able to accomplish using y'all's - especially Aacini's - responses)
For a Rational BuildForge project, I have environment variables defined for each deployment target host. Example:
CURAM_HOST_NAME_DEV=DDW5T
CURAM_HOST_NAME_UAT=DUW5T
CURAM_HOST_NAME_TRN=DTW5T
CURAM_HOST_NAME_PRD=DPW5P
Another variable HOST contains the environment to deploy to. The deployment code is common for all deployment targets and uses the variable CURAM_HOST_NAME, so I needed to set this variable to the value of the variable that corresponds to the HOST being deployed to. The following does the trick:
#ECHO OFF
SET CURAM_HOST_NAME_DEV=DDW5T
SET CURAM_HOST_NAME_UAT=DUW5T
SET CURAM_HOST_NAME_TRN=DTW5T
SET CURAM_HOST_NAME_PRD=DPW5P
SET HOST=DEV
CALL ECHO %%CURAM_HOST_NAME_%HOST%%%
SET HOST=UAT
CALL ECHO %%CURAM_HOST_NAME_%HOST%%%
SET HOST=TRN
CALL ECHO %%CURAM_HOST_NAME_%HOST%%%
SET HOST=PRD
CALL ECHO %%CURAM_HOST_NAME_%HOST%%%
Output:
DDW5T
DUW5T
DTW5T
DPW5P
In the BuildForge step, the code that sets this particular variable looks like the following:
.bset env "CURAM_HOST_NAME=`CALL ECHO %%%CURAM_HOST_NAME_%%HOST%%%%`"
(The BF parser requires additional %'s)
For a value of DEV for the HOST variable this produces the following in the log:
1026 5/3/14 7:34 PM STEP .bset env "CURAM_HOST_NAME=`CALL ECHO %%%CURAM_HOST_NAME_%%HOST%%%%`"
1027 5/3/14 7:34 PM EXEC .bset env 'CURAM_HOST_NAME' = 'DDW5BTH
Thanks a lot everyone. Wish I had the reputation that would allow me to upvote your answers!
Jozef
#echo off
SET A=This
SET B=That
SET ThisThat=YES!
call echo %%%A%%B%%%
EDIT: Updated answer to an updated question!
#ECHO OFF
SET CURAM_HOST_NAME_DEV=DDW5T
SET CURAM_HOST_NAME_UAT=DUW5T
SET CURAM_HOST_NAME_TRN=DTW5T
SET CURAM_HOST_NAME_PRD=DPW5P
for %%a in (DEV UAT TRN PRD) do CALL ECHO %%CURAM_HOST_NAME_%%a%%
However, you should note that the !variable! replacement (together with setlocal EnableDelayedExpansion) run much faster than the CALL echo %%variable%% trick:
#ECHO OFF
setlocal EnableDelayedExpansion
SET CURAM_HOST_NAME_DEV=DDW5T
SET CURAM_HOST_NAME_UAT=DUW5T
SET CURAM_HOST_NAME_TRN=DTW5T
SET CURAM_HOST_NAME_PRD=DPW5P
for %%a in (DEV UAT TRN PRD) do ECHO !CURAM_HOST_NAME_%%a!
Perhaps you may want to review this post
#echo off
setlocal enableDelayedExpansion
set "A=this"
set "B=that"
set "thisthat=YES^!"
echo !%A%%B%!
Note that the exclamation must be escaped in the assignment of thisthat because delayed expansion is enabled.
I want to do something like this in batch script. Please let me know if this is the proper or possible way to do it or any other way?
set var1=A
set var2=B
set AB=hi
set newvar=%var1%%var2%
echo %newvar%
This should produce the value "hi".
Enabling delayed variable expansion solves you problem, the script produces "hi":
setlocal EnableDelayedExpansion
set var1=A
set var2=B
set AB=hi
set newvar=!%var1%%var2%!
echo %newvar%
You can do it without setlocal, because of the setlocal command the variable won't survive an endlocal because it was created in setlocal. In this way the variable will be defined the right way.
To do that use this code:
set var1=A
set var2=B
set AB=hi
call set newvar=%%%var1%%var2%%%
echo %newvar%
Note: You MUST use call before you set the variable or it won't work.
The way is correct, but can be improved a bit with the extended set-syntax.
set "var=xyz"
Sets the var to the content until the last quotation mark, this ensures that no "hidden" spaces are appended.
Your code would look like
set "var1=A"
set "var2=B"
set "AB=hi"
set "newvar=%var1%%var2%"
echo %newvar% is the concat of var1 and var2
echo !%newvar%! is the indirect content of newvar