In the following (simplified example) batch file I am having difficulty correctly setting Y:
#Echo off
setlocalenabledelayed Expansion
set EqS=Nope
set X=Eq
set Y=%X%S
echo Y
How can I get the output of this script to be Nope instead of EqS?
As Karl ask, there could be different meanings of your question.
I try to give an answer for each possibility
#echo off
setlocal EnableDelayedExpansion
set EqS=Nope
set X=Eq
REM set Y1 to "EqS"
set Y1=%X%S
REM set Y2 to "Nope" (content of EqS)
set Y2=!%X%S!
REM set Y3 to "!EqS!"
set Y3=^^!%X%S^^!
echo %Y1%
echo %Y2%
echo %Y3%
set EqS=Something
echo(
echo Text %Y1%
echo Content %Y2%
echo Pointer %Y3%
Related
In my batch I want to copy a variable amount of source- to target destinations.
I want to define like this:
#setlocal EnableDelayedExpansion
set source1="C:\folder1"
set target1="f:\folder1"
set source2="C:\folder2"
set target2="f:\folder2"
...
set sourcen="C:\foldern"
set targetn="f:\foldern"
Dependently from a defined amount of folders
set numFolder=5
I want to go through the folders in a loop:
set /a COUNT=0
:LOOP
echo %COUNT%
set /a COUNT+=1
rem write the NAME of the parameter variable (source1,source2 etc.) in nameor
set "nameor=source%COUNT%"
rem write the VALUE of the parameter variable (source1,source2 etc.) into origin ("C:\folder1", "C:\folder2")
set "origin=%nameor%"
echo %origin%
if %COUNT% lss %numFolder% goto LOOP
When I show
echo %nameor%
I get what I expectet: source1, source2 etc.
but
echo %%%origin%%%
only provides
source1
instead of the expected value
"C:\folder1"
I thought, that I could resolve this by using DelayedExpansion but what did I miss?
To avoid confusion for me, I change the "origin" to "source". E.g. set "origin=%nameor%" changed to set "source=%nameor%".
To print out "C:\folder1" to "C:\foldern", you should use echo !%source%!, else you will just see "source1" to "sourcen".
Your problem is just about array element management. Try this:
#echo off
setlocal EnableDelayedExpansion
rem Define the two arrays
set i=0
for %%a in ("C:\folder1=f:\folder1"
"C:\folder2=f:\folder2"
"C:\foldern=f:\foldern") do (
set /A i+=1
for /F "tokens=1,2 delims==" %%b in (%%a) do (
set source!i!="%%a"
set target!i!="%%b"
)
)
rem Show up to numFolder elements of both arrays
set numFolder=5
for /L %%i in (1,1,%numFolder%) do (
echo %%i- Source%%i=!source%%i!, Target%%i=!target%%i!
)
The first part is equivalent to your series of individual element assignments. In this way is easier to add new pairs of values.
For further description on array management in Batch files, see: Arrays, linked lists and other data structures in cmd.exe (batch) script
In windows batch could you set a variable within a variable?
Explained:
So the %num% is within the variable.
set num=5
set cnum=test
set h1=%c%num%%
Is it possible to make the percents work like parenthesis?
The output should be h1=test
Any help would be appreciated.
Your example in your question is a mess, but I think I understand what you are looking for:
#echo off
setlocal
set C1=apple
set C2=orange
set C3=banana
set num=2
:: Inefficient way without delayed expansion
:: This will be noticeably slow if used in a tight loop with many iterations
call echo %%C%num%%%
:: The remaining methods require delayed expansion
setlocal enableDelayedExpansion
:: Efficient way 1
echo(
echo !C%num%!
:: Efficient way 2 - useful if inside parenthesized block
:: where %num% will not give current value
echo(
for %%N in (!num!) do echo !C%%N!
:: Showing all values via a loop
echo(
for /l %%N in (1 1 3) do echo !C%%N!
You may be looking for the Call Set command. This sets cnum to string c1, c2, c3 etc. It changes each time %num% changes. You can then use Call Set to assign any variable (h1 for example) to the value of the variable cnum stands for.
#echo off
setlocal enabledelayedexpansion
set c5=test
set num=5
:: set cnum to string "c5"
set cnum=c%num%
:: set h1 to to the existing variable c5
call set "h1=%%%cnum%%%"
echo %h1%
Are you after something like this?
cls
#echo off
setlocal EnableDelayedExpansion
Set num=5
Set "c!num!=test"
Echo !c5!
See http://ss64.com/nt/delayedexpansion.html for more info on delayed expansion.
cls
#echo off
setlocal EnableDelayedExpansion
set num=4
set c1=this is a demo
set c2=second example
set c3=third
set c4=this is the one I want
set c5=last
Echo !c%num%!
I have a variable "var1" with contents of "sharp=soothe"
var1=sharp=soothe
How do I create a new variable using only var1 contents to get this
sharp=soothe
I want to use the set command somehow like this
set %var1%=
but I can't get further than this. I hope I don't have to search for strings before and after the = sign. I thought there would be a faster way than that.
OK, I am so close. I found some other code I'm using and this nearly works for an infinite number of variables but the set command syntax is wrong again.
set var1=unfilter=rem
set var2=mdegrain=rem
set n=0
:parseArgs2
set /a n+=1
if defined var%n% (
set %var%n%%
shift /1
goto :parseArgs2
)
Just remove one character from your attempt :-)
set %var1%
If you have an "array" of variables: var1, var2, ... var20, then you can use a FOR /L loop with delayed expansion:
setlocal enableDelayedExpansion
rem define your variables here ...
for /l %%N in (1 1 20) do set !var%%N!
Or if you have a series of randomly named variables, a simple FOR will do:
setlocal enableDelayedExpansion
rem define your variables here ...
for %%V in (varA varB varC varD) do set !%%V!
update in response to add-on question
I don't see why you are using SHIFT, unless there is other code you haven't shown. I removed the SHIFT.
set var1=unfilter=rem
set var2=mdegrain=rem
set n=0
:parseArgs2
set /a n+=1
if defined var%n% (
call set %%var%n%%%
goto :parseArgs2
)
or
setlocal enableDelayedExpansion
set var1=unfilter=rem
set var2=mdegrain=rem
set n=0
:parseArgs2
set /a n+=1
if defined var%n% (
set !var%n%!
goto :parseArgs2
)
Try this:
set var1=sharp=soothe
for /f "tokens=*" %%a in ("%var1%") do set %%a
echo %sharp%
or just:
for %%a in ("%var1%") do set %%a
Perhaps is this what you want?
#echo off
setlocal EnableDelayedExpansion
set var1=unfilter=rem
set var2=mdegrain=rem
set var10=resize=rem
for /F "tokens=1* delims==" %%a in ('set var') do set %%b
In this method does not matter the number of defined variables nor its order; all defined variables are always processed.
EDIT: Below is the output when an ECHO command is placed before the set %%b:
set unfilter=rem
set resize=rem
set mdegrain=rem
I have a batch file that pulls in all the command line arguments and stores them as variables. I then search for a name in each, then make a new variable of that name but with new content (rem). I have the first search done here but I don't know how to search all the others without repeating the same commands. I tried it by doing that and it didn't work. Anyway if there is an easier way than this please tell.
#echo off
setlocal enableDelayedExpansion
set var1=noisereduction-01
set var2=sharpener-03
set var3=resize-02
set var4=output-01
set var5=grain-02
set var6=crf-21
set var7=preset-veryfast
set var8=tune-film
set var9=ref-2
set var10=outputdir-g:\output
set var11=mode-3
for /l %%N in (1 1 11) do call :test var%%N
exit /b
:test variableName
echo !%1!|>nul findstr /rx .*noisereduction.* && set !%1!=rem
echo %1 = !%1!
exit /b
Whoops, there is an error above. I want to create a new var with the name of "noisereduction-01" and a value of "rem", not just give var1 a value of rem. I thought the set !%1!=rem would do it but it is not.
Let's see this problem. When
set var1=noisereduction-01
... and
for /l %%N in (1 1 11) do call :test var%%N
... then the first call to test is with "var1" parameter. This mean that into test:
set !%1!=rem IS set !var1!=rem IS set noisereduction-01=rem
... that correctly do what you want.
HOWEVER:
echo %1 = !%1! IS echo var1 = !var1! IS echo var1 = noisereduction-01
If you want to show the value of noisereduction-01 variable, then you must perform an additional expansion step:
for %%v in (!%1!) do echo param: %1, variable: !%1!, value: !%%v!
I am trying to get nested variables in my batch game i am creating.
I want it so that it will choose a random variable and change it to X, but if it is already chosen, it should go back and choose a different number.
set 1=a
set 2=b
set 3=c
set 4=d
set 5=e
those were the variables, here is the code
setlocal enabledelayedexpansion
:eliminator
set /a eliminate=(%random * 5) / 32767 + 1
if %%eliminate%%==X goto eliminator
echo The letter !!eliminate!! was chosen
timeout 5
set %%eliminate%%=X
goto eliminator
Now, the thing is, when I try to echo it, it writes the name of the variable instead of the value. Also, variables that have already been chosen are being chosen again. Any way I could fix this? Thanks.
try this:
#echo off&setlocal
set "var1=a"
set "var2=b"
set "var3=c"
set "var4=d"
set "var5=e"
:loop
set /a rd=%random%%%5+1
if defined var%rd% call echo %%var%rd%%%
set "var%rd%="
set "var" >nul 2>&1 && goto:loop
..output (may vary):
d
a
c
b
e
Your posted code is missing the closing % around random - it should read %random%.
Your formula for a random number between 1 and 5 is more complicated than need be. I would use:
set /a eliminate=%random% %% 5 + 1
To expand a "nested variable" you need !%eliminate%!
But I would completely rewrite your algorithm. I think the following does what you want:
#echo off
setlocal enableDelayedExpansion
set "chars=abcde"
set charCnt=5
:loop
set /a "pos=%random% %% charCnt, pos2=pos+1, charCnt-=1"
set "letter=!chars:~%pos%,1!"
echo The letter %letter% was chosen
set "chars=!chars:~0,%pos%!!chars:~%pos2%!"
if defined chars goto loop
The script is optimized to always pick a valid unused letter on each iteration.