Use a variable on SET in Windows batch file - batch-file

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%

Related

How to refer to a variable in Batch Scripting?

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%

How to solve this batch glitch?

I have a little problem in my code,
if I
set ghot=1
and
set fo1=text
and try echoing
echo %fo%ghot%%
like this, it comes like
%fo1%
instead of text
I misunderstood what you were asking at first. Adding call to the line will give you the behavior you want.
call echo %%fo%ghot%%%
Edited to add the extra enclosing %'s It works without them from the command line, but not from within a batch file.
An alternative method using delayed expansion:
#Echo Off
SetLocal EnableDelayedExpansion
Set "ghot=1"
Set "fo1=text"
Echo=!fo%ghot%!
Timeout -1

Nested Variables in Substring selection

I'm struggling to get this "Substring"-Selection done dynamically:
set input=%input:~4%
I would like to have something like
set input=%%input:~%length% %%
But all my attempts with double %% and ! and many more have failed. Hope you can tell me, how nested variables like this work in windows batch files.
Many thanks in advance,
best regards,
marcus
Many possible ways
This uses the fact that CALL starts the batch parser a second time
set length=4
call set input=%%input:~%length%%%
With delayed expansion it's the most stable and secure solution
setlocal EnableDelayedExpansion
set length=4
set input=!input:~%length%!
Sometimes it's even useful to use a FOR parameter
setlocal EnableDelayedExpansion
set length=4
for /F %%n in ("!length!") do (
set input=!input:~%%~n!
)

Nested variable name using EnableDelayedExpansion

I am working on a script to get max lengths of each column, I'm trying to store lengths of max length in _c1...n vars. number of columns unknown.
I was able to get length for each column, create variables to store each with set _c!i! = !n!, n is the length
but in order to set the max length for a particular column I need to compare current with max and use something like !_c!!i!! which doesn't work, any ideas how to refer a variable which part of it's name coming from another variable?
Thanks...
I assume that you are using the delayed expansion character because you are working inside a set of brackets "()". Doing that makes your process harder. I know that method is easier to read, but it is harder to code for.
Inside brackets, I know of only one method to access a variable that was 'built' out of one or more variables. That is to use the call function to cause the assembled variable to 'activate'. This method works both inside and outside of brackets.
Here is a small example:
#echo off
setlocal enabledelayedexpansion
(
set i=10
set _c!i!=something
:: below is equivalent to echo !_c10!
call echo %%_c!i!%%
)
endlocal
Output:
something
You can do almost everything using a CALL in front of it that you can without it, though in XP or earlier you cannot call internal commands like if and can only call 'external' programs like FIND.EXE.
If you can work outside of a set of brackets by possibly using a call :label statement, you can simply access the variable like this:
#echo off
setlocal enabledelayedexpansion
set i=10
set _c!i!=something
:: The below 2 statements are equivalent to `echo %_c10%`
echo !_c%i%!
call echo %%_c!i!%%
endlocal
Output:
something
something
The CALL technique suggested by James K will work, but it is relatively slow and can be unsafe, depending on the content of the variable.
The following looks more complicated, but it is significantly faster and more reliable:
for %%A in (!i!) do echo !_c%%A!
In your case there could be a third solution be possible, if your variables contains only numbers.
#echo off
setlocal enabledelayedexpansion
(
set i=10
set _c!i!=4711
set /a tmp=_c!i!
echo !tmp!
)
This works, as SET /A can access the content of a variable without the nedd of explicitly expansion charaters.

how concatenate two variables in batch script?

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

Resources