How to access a variable using content of another variable as name? - windows

I would access the value of a variable. The name of the variable I want to access is stored in another variable and/or passed by argument to the batch.
So, I want to achieve two things:
calling batch with desired variable name as argument (and batch accessing the var directly):
--> command line==batch.bat myVar
{batch file:}
echo (what is in variable myVar)
calling batch with variable name that holds another varibale's name and output that other variable:
Let's assume that the variable "var_name" exists and has the value "APPDATA"
--> command line==batch.bat var_name
{batch file==}
echo (what is in variable APPDATA)

Not 100% sure why you need this, but I am assuming you want something like:
#echo off & setlocal enabledelayedexpansion
set "var=appdata"
for %%i in (!%1!) do (
echo original val from variable "%1" = "%%i"
echo secondary val from variable "%%i" = "!%%i!"
)
Here, I have set a temp value for var to be appdata. When running scriptname.cmd var you'll get the relevant results for both variables var and its value appdata

Related

How to assign decimal to variable on windows command line?

echo %time:~-5% returns a 5-character string, such as
18.09
However, i cannot seem to set that string to a variable:
set start = %time:~-5%
echo %start%
returns
10:07:18.09
what's simple way to get those last 5 chars into a variable?
thx
Windows doesn't like space next to =. So try this ...
set start=%time:~-5%
echo %start%

Batch file does not echo empty string value, leaves %var1% in output

I thought that batch files would allow for empty variable to be output as a null string (""). If I set var1 to nothing, I thought I should
set "var1="
echo Variable value is: %var1%
I thought I'd get this:
Variable value is:
I actually get this as the output:
Variable value is: %var1%
Why isn't the var1 variable evaluating a blank string? For the record, I tested this with a new CMD instance in Windows 7.

how to pass comma separated parameter to batch file and use if else in batch file?

I have one batch file MyTest.bat
MyTest.bat
call "first.bat"
call "second.bat"
call "third.bat"
Now while executing MyTest.bat I will pass comma separated parameters like
call MyTest.bat first.bat,second.bat
now inside MyTest.bat I want to check which parameters are passed and based on those using if else condition
I want to execute internal statements.
for example something like it
MyTest.bat first.bat,second.bat
now inside
I will check
get all parameters list param[] = {first.bat,second.bat}
if param[i] == "first.bat"
{
call "first.bat"
}
else if param[i] == "second.bat"
{
call "second.bat"
}
else if param[i] == "third.bat"
{
call "third.bat"
}
// this assures that what parameters I passed only those statements gets executed not other.
The above code is just a pseudo code how can write actual MyTest.bat?
Next script requires another parameter order (list of batch names down to end all other parameters):
#ECHO OFF
SETLOCAL EnableExtensions
rem usage: 33955749.bat name address "first script", second, third
:loop
if "%~3" == "" goto :next
if exist "%~n3.bat" (
call "%~n3.bat" %1 %2
) else (
echo can't found file; failed call "%~n3.bat" %1 %2
)
shift /3
goto :loop
:next
For debugging purposes, prepare sample files "first script.bat" and second.bat; ensure that third.bat does not exist:
==> >"first script.bat" echo #echo %~nx0 parameters: %%*=%*
==> >second.bat echo #echo %~nx0 parameters: %%*=%*
==> 2>NUL del third.bat
Output (shows independency on used delimiters):
==> 33955749 name address "first script", second, third
first script.bat parameters: %*=name address
second.bat parameters: %*=name address
can't found file; failed call "third.bat" name address
==> 33955749 name address "first script" second; third
first script.bat parameters: %*=name address
second.bat parameters: %*=name address
can't found file; failed call "third.bat" name address
Another approach: fist parameter = list of comma-separated batch names surrounded with a pair of double quotes:
#ECHO OFF
SETLOCAL EnableExtensions
rem usage: 33955749b "first script,second,third" name address
rem no spaces surrounding commas or names
rem wrong: 33955749b " first script , second, third" would fail
set "_names=%~1"
set "_names=%_names:,=","%"
rem debug echo _names="%_names%"
for %%G in ("%_names%") do (
if exist "%%~dpnG.bat" (
call "%%~dpnG.bat" %2 %3
) else (
echo can't found script; failed call "%%~dpnG.bat" %2 %3
)
)
Output (shows responsivity to used delimiters):
==> 33955749b "first script,second,third" name address
first script.bat parameters: %*=name address
second.bat parameters: %*=name address
can't found script; failed call "D:\bat\SO\third.bat" name address
==> 33955749b "first script, second,third" name address
first script.bat parameters: %*=name address
can't found script; failed call "D:\bat\SO\ second.bat" name address
can't found script; failed call "D:\bat\SO\third.bat" name address
Note that both 33955749.bat and 33955749b.bat scripts
accept (partially or fully qualified) paths to called scripts, even with space(s);
on the other hand, they both ignore file extension(s) even if supplied and force .bat.
For instance, 33955749 name address first.cmd second.cmd would attempt to call first.bat and second.bat.
Resources (required reading, incomplete):
(command reference) An A-Z Index of the Windows CMD command line
(additional particularities) Windows CMD Shell Command Line Syntax
(%~G, %~1 etc. special page) Command Line arguments (Parameters)
(%variable:StrToFind=NewStr% etc.) Variable Edit/Replace

What syntax will check if a variable name containing spaces is defined?

Windows user defined environment variable names can contain any character except =.
Special characters can be included by escaping them. A simpler method is to simply enclose the entire SET expression within quotes. For example:
set "A weird & "complex" variable=My value"
set A weird ^& "complex" variable=My value
Both expressions above give the same result. The variable name is A weird & "complex" variable and the value is My value
The IF DEFINED construct is used to test if a variable is defined. Quotes don't work for this test, special characters in the name (including quotes) must be escaped.
set "A&B=value"
if defined A^&B echo This works
if defined "A&B" echo This does not work
The above escaped test works just fine. The quoted test does not work
But how can I test if a variable containing spaces exists?
set "A B=value"
if defined A^ B echo this does not work!
It seems like the above should work, but it doesn't!
I'm looking for an answer that does NOT involve expanding the variable using %A B% or !A B!
Interessting question (I love this syntax base questions).
Obviously you know how to check it with delayed expansion and also FOR-parameters works.
#echo off
setlocal
set "AAA BBB=value"
set ""AAA BBB"="
set "AAA="
for %%a in ("AAA BBB") do if defined %%~a echo FOR: This works
setlocal EnableDelayedExpansion
set "varname=AAA BBB"
if defined !varname! echo Delayed: This works
if defined %varname% ( echo percent: Never comes here
) ELSE ( echo percent: Never comes here ? )
if defined AAA^ BBB ( echo escape1: Never comes here
) ELSE ( echo escape1: fails )
set AAA=Hello
if defined AAA^ BBB (
echo escape2: It only test for AAA the BBB will be "removed"
) ELSE ( echo escape2: fails )
set "space= "
if defined AAA!space!BBB echo inject space: This works
if defined "AAA BBB" (echo Quote1: Never comes here
) ELSE ( echo Quote1: Fails )
set ""AAA BBB"=value"
if defined "AAA BBB" echo Quote2: This works, it checks for "AAA BBB" with quotes
In my opionion, in the escape2 example the parser first split the line into tokens this way:
<if> <defined> <AAA BBB> <echo ....
But at the execution time of the if defined it rescan the <AAA BBB> token so it only gets the AAA.
You can't inject a second escape like AAA^^^ BBB as this only searches for the variable named AAA^
I can't see a solution without delaying/FOR, as the escaping of the space always fails.
EDIT: It can also be solved with SET <varname>
The solution of ijprest uses the SET command to test the variable without the need of escaping the varname.
But it also shows interessting behaviour with spaces inside and at the end of a varname.
It seems to follow these rules:
SET varname searches for all variables beginning with varname, but first it removes all characters after the last space character of varname, and it removes all leading spaces.
So you can't search for variables with beginning with space (but it is also a bit tricky to create such a varname).
The same behaviour is also active if the variablename is enclosed into quotes, but then exists one more rule.
First remove all characters after the last quote, if there are at least two quotes.
Use the text inside of the quotes, and use the "space"-rule.
Sample.
set " abc def ghi" junk junk
*** 1. removes the junk
set " abc def ghi"
*** 2. removes the quotes
set abc def ghi
*** 3. removes all after the last space, and the trailing spaces
set abc def
*** Search all variables beginning with abc def
I also love this sort of question! :)
Here's another possible solution I came up with... using SET itself to test the existence, and using the ERRORLEVEL result:
set "A B=foo"
set A B >nul 2>nul&& echo 1. This works
set "A B ">nul 2>nul&& echo 2. This works
set "A weird & "complex" variable=foo"
set A weird ^& "complex" variable >nul 2>nul&& echo 3. This works
set "A weird & "complex" variable ">nul 2>nul&& echo 4. This works
Note that this only works if your variables are unique in the sense that no variable name is the prefix of another one. Otherwise you risk false positives, as SET's default behavior is to show all variables that start with the parameter you pass. If this could be the case, you could filter the results with findstr:
set "A B="
set "A B C=foo"
set "A B ">nul 2>nul&& echo 5. Failed (false positive)
set "A B "|findstr /B /L /C:"A B=" >nul||echo 6. This works (no false positive)
Also, the single trailing space after the variable name seems to be required. Without it, SET often mis-parses the input. Bizarrely, if you add an extra space between the "2>nul" and "&&" in case #3 it stops working (unless you remove the space before ">nul")... weird.
The other way is to reassign it to another variable (one without spaces) and test that. See here:
rem Prepare ONLY variable 'a b'
set "a b=123"
echo [a b]=%a b%
rem This will ouput: [a b] is defined
set var=%a b%
if defined var (
echo [a b] is defined
) else (
echo [a b] is not defined
)
rem This will output: [c d] is not defined
set var=%c d%
if defined var (
echo [c d] is defined
) else (
echo [c d] is not defined
)
I do it by defining a flag as TRUE if needed...
rem /* sample code */
set VAR_SET=
if <some condition> set VAR_SET=TRUE&set VAR=this data has spaces
rem /* test for VAR_SET using 'if defined' */
if defined VAR_SET (
rem /* do something with the other data in the variable %VAR% */
)
rem /* clear the flag */
set VAR_SET=

assigning an alphanumeric value to a variable in batch

I want to assign the alpha numeric value to one variable in Batch scripting.
I tried following one but getting error.
setlocal
set test = \765514e2aad02ca658cc56cdb7884947 *E:\\test1
echo %test%
endlocal
Error:
C:\Users\bgannu>setlocal
C:\Users\bgannu>set test = \765514e2aad02ca658cc56cdb7884947 *E:\\test1
C:\Users\bgannu>echo 0
0
C:\Users\bgannu>endlocal
The syntax for set is set [[/a [expression]] [/p [variable=]] string]
The = has to be directly after your variable so you need to change:
set test = \765514e2aad02ca658cc56cdb7884947 *E:\\test1
to:
set test=\765514e2aad02ca658cc56cdb7884947 *E:\\test1
Otherwise your variable name would have a space at the end. You can easily try this out:
> set bar = foo
> echo %bar%
%bar%
> echo %bar %
foo
Note that both the variable name and its content got a space.
Lose the /A. the /A is used for arithmetic.
C:\test>set var=\765514e2aad02ca658cc56cdb7884947 *E:\\test1
C:\test>echo %var%
\765514e2aad02ca658cc56cdb7884947 *E:\\test1

Resources