Colon in batch variable name - windows

I have a batch script which should have access to a variable named something like env:dev, so it has a colon inside... this variable is set by a third-party component, so I don't have influence on that naming...
How can I access the content of this variable in my batch script? I know that : is a special character, so can I perhaps escape it? The following doesn't work:
echo %env:dev%
echo "%env:dev%"
echo %env^:dev%
...
Any suggestions?

A : colon has special meaning in CMD environment variables if command extensions are enabled (Windows cmd default), for instance
Variable Edit/Replace:
%variable:StrToFind=NewStr%
Variables: extract part of a variable (substring):
%variable:~num_chars_to_skip%
%variable:~num_chars_to_skip,num_chars_to_keep%
Hard to escape a : colon in variable name, if possible at all. Here's a workaround: create variables with such names that : colon is replaced by another character, e.g. _ Low Line (underscore):
#ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
rem create sample variables
set "env:dev1=some thing!" value contains exclamation mark
set "env:dev2=some thing%%" value contains percent sign
set "an:other=some:thing3" another name containing colon
echo --- before ---
set env
set an
for /F "tokens=1* delims==" %%G in ('set') do (
set "auxName=%%G"
set "auxValue=%%H"
call :colons
)
echo --- after ---
set env
set an
rem
ENDLOCAL
goto :eof
:colons
if not "%auxName::=_%" == "%auxName%" set "%auxName::=_%=%auxValue%"
goto :eof
Output:
==> d:\bat\so\37973141.bat
--- before ---
env:dev1=some thing!
env:dev2=some thing%
an:other=some:thing3
--- after ---
env:dev1=some thing!
env:dev2=some thing%
env_dev1=some thing!
env_dev2=some thing%
an:other=some:thing3
an_other=some:thing3
==>
Edit: for the sake of completeness:
#ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
rem create sample variables
set "env:dev1=some thing!" value contains exclamation mark
set "env:dev2=some thing%%" value contains percent sign
set "an:other=some:thing3" another name containing colon
rem use sample variables
SETLOCAL DisableExtensions
echo Disabled Extensions %env:dev1% / %env:dev2% / %an:other%
ENDLOCAL
Be aware of disabling command extensions impact, read cmd /?:
The command extensions involve changes and/or additions to the
following commands:
DEL or ERASE
COLOR
CD or CHDIR
MD or MKDIR
PROMPT
PUSHD
POPD
SET
SETLOCAL
ENDLOCAL
IF
FOR
CALL
SHIFT
GOTO
START (also includes changes to external command invocation)
ASSOC
FTYPE
To get specific details, type commandname /? to view the specifics.

Related

Why does my batch script not interpret a string correctly

In my second if statement, I want to filter out "tool" or "tool.bat" from the final list of filenames. However, the final list of filenames includes "tool" and total_bags is being incremented. I was wondering what I did incorrectly that's causing the program to not catch this case.
set /A total_bags=0
set target=%~1
if "%target%"=="" set target=%cd%
set LF=^
rem Previous two lines deliberately left blank for LF to work.
for /f "tokens=1 delims=. " %%i in ('dir /b /s /a:-d "%target%"') do (
set current_file=%%~ni
echo !unique_files! | find "!current_file!:" > nul
if NOT !ERRORLEVEL! == 0 (
if NOT !current_file! == "tool.bat" (
set /A total_bags=total_bags+1
set unique_files=!unique_files!!current_file!:
)
)
)
echo %unique_files::=!LF!%
echo %total_bags%
endlocal
The condition if NOT "%current_file%" == "tool.bat" as initially used does not work because of %current_file% is replaced already by current string of the environment variable current_file respectively an empty string on Windows command processor is processing the entire command block starting with ( and ending with matching ) before executing command FOR. That can be seen on debugging the batch file. See also Variables are not behaving as expected for a very good and short example explaining how the Windows command interpreter (CMD.EXE) parses scripts.
It is in general not advisable to assign the string already assigned to a loop variable to an environment variable which is not further modified inside a FOR loop. It would be better to use %%~ni everywhere in your code on which the current file name needs to be referenced.
The usage of delayed expansion requires enabling it with setlocal EnableDelayedExpansion (or with setlocal EnableExtensions EnableDelayedExpansion to enable explicitly also the command extensions enabled by default) as it is not enabled by default in comparison to the command extensions. Then the Windows command processor parses each command line a second time and expands !current_file! on execution of command IF.
But even if NOT !current_file! == "tool.bat" evaluates always to true for the batch file with name tool.bat because of set current_file=%%~ni results in assigned to the environment variable current_file only the string tool (file name without file extension) and the left string is not enclosed in double quotes while the right string is always enclosed in double quotes. The command IF does not remove the double quotes from right string before comparing the two strings.
The batch file in question misses also set unique_files= above the FOR loop to undefine explicitly the environment variable unique_files in case of being already defined by chance on starting the batch file, for example from a previous execution within a command prompt window.
Another problem with the batch file in question is that maximum string length of variable name + equal sign + string assigned to the environment variable is 8191 characters which is a problem on several thousands of file names are concatenated to a long string assigned to one environment variable like unique_files.
I suggest to use this batch file with comments explaining it.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Delete all environment variables of which name starts very unusual
rem with a question mark existing already by chance (with exception of
rem those environment variables with multiple question marks in name).
for /F "delims=?" %%I in ('set ? 2^>nul') do set "?%%I?="
rem Search with the string passed as first argument or simply within current
rem directory recursively for all files and define for each file name an
rem environment variable with a question mark at beginning and one more at
rem end of the variable name. A file name cannot contain a question mark.
rem The value assigned to the environment variable does not matter. As it
rem is not possible to define multiple environment variables with same name
rem and environment variable names are case-insensitive, there is just one
rem environment variable defined on multiple files have same file name.
rem The batch file itself is ignored because of the IF condition.
for /F "delims=" %%I in ('dir "%~1" /A-D /B /S 2^>nul') do if not "%%I" == "%~f0" set "?%%~nI?=1"
rem Initialize the file counting environment variable.
set "FileCount=0"
rem Output all file names which are the environment variable names sorted
rem alphabetically with the question marks removed and additionally count
rem the number of file names output by this loop.
for /F "eol=| delims=?" %%I in ('set ? 2^>nul') do set /A "FileCount+=1" & echo %%I
rem Output finally the number of unique file names excluding file extensions.
echo %FileCount%
rem Restore initial execution environment which results also in the
rem deletion of all environment variables defined during batch execution.
endlocal
It does not use delayed expansion and for that reason works also for file names containing one or more ! in file name which would be processed wrong on enabling delayed expansion on line set current_file=%%~ni because of the exclamation mark(s) in file name would be interpreted as begin/end of a delayed expanded environment variable reference.
There is defined an environment variable for each unique file name. The number of environment variables is limited only by the total available memory for environment variables which is 64 MiB. That should be enough even for several thousands of unique file names in the directory tree.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /? ... explains %~f0 which references full name of argument 0 which is the full qualified file name of the currently processed batch file and %~1 referencing first argument with perhaps existing surrounding " removed from argument string.
dir /?
echo /?
endlocal /?
for /?
if /?
rem /?
set /?
setlocal /?
Read the Microsoft documentation about Using command redirection operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on the FOR command lines to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir or set command line with using a separate command process started in background with %ComSpec% /c and the command line within ' appended as additional arguments.

Reading lines from a txt file into variables in batch

I am trying to figure out how to read IP addresses from a file named "IPList.txt) into individual variables in a batch script. Here's what I have so far.
:DEFINITIONS
set LOGFILE=IPScript.log
set IPLIST=C:\IPLIST.txt
echo Script Started >> %LOGFILE%
goto SetIP
:SetIP
for /f "tokens=*" %%a in (%IPLIST%) do (
set FirstIP=%%a
)
echo The first IP is %FirstIP% >> %LOGFILE%
exit
The output I'm getting in "IPscript.log" is "The First IP is: " with no IP listed, just a space. Also, is there a way for me to set multiple IPs like this, in just one for loop?
Here's a quick example to assist you:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
:DEFINE_LOCAL_VARIABLES
Set "IPLIST=C:\IPLIST.txt"
Set "LOGFILE=IPScript.log"
:CHECK_SOURCE_EXISTS
For %%G In ("%IPLIST%") Do If "%%~aG" Lss "-" (
Echo The file %IPLIST% does not exist.
Echo Press any key to end this script.
Pause 1> NUL
GoTo :EOF
) Else If "%%~aG" GEq "d" (
Echo Expected a file, but %IPLIST% is a directory.
Echo Press any key to end this script.
Pause 1> NUL
GoTo :EOF
)
:UNDEFINE_LOCAL_VARIABLES
For /F "Delims==" %%G In ('"(Set IP[) 2> NUL"') Do Set "%%G="
:START_MAIN
Set "i=1000"
(
Echo Script Started
For /F UseBackQ^ Delims^=^ EOL^= %%G In ("%IPLIST%") Do (
Set /A i += 1
SetLocal EnableDelayedExpansion
For %%H In ("!i:~-3!") Do (
EndLocal
Set "IP[%%~H]=%%G"
Echo IP[%%~H] is %%G
)
)
) 1> "%LOGFILE%"
:CHECK_IP_VARIABLES_EXIST
If Not Defined IP[001] (
Echo %IPLIST% had no readable file content.
Echo Press any key to end this script.
Pause 1> NUL
GoTo :EOF
)
:VIEW_IP_VARIABLES
Set IP[
Pause & GoTo :EOF
If you have an existing %LOGFILE%, and you intend to append to it, (as opposed to overwrite/create one), change 1> "%LOGFILE%" to 1>> "%LOGFILE%".
If you didn't really need %LOGFILE%, e.g. it was used by you just for testing, it would look a little more like this:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
:DEFINE_LOCAL_VARIABLES
Set "IPLIST=C:\IPLIST.txt"
:CHECK_SOURCE_EXISTS
For %%G In ("%IPLIST%") Do If "%%~aG" Lss "-" (
Echo The file %IPLIST% does not exist.
Echo Press any key to end this script.
Pause 1> NUL
GoTo :EOF
) Else If "%%~aG" GEq "d" (
Echo Expected a file, but %IPLIST% is a directory.
Echo Press any key to end this script.
Pause 1> NUL
GoTo :EOF
)
:UNDEFINE_LOCAL_VARIABLES
For /F "Delims==" %%G In ('"(Set IP[) 2> NUL"') Do Set "%%G="
:START_MAIN
Set "i=1000"
Echo Script Started
For /F UseBackQ^ Delims^=^ EOL^= %%G In ("%IPLIST%") Do (
Set /A i += 1
SetLocal EnableDelayedExpansion
For %%H In ("!i:~-3!") Do (
EndLocal
Set "IP[%%~H]=%%G"
)
)
:CHECK_IP_VARIABLES_EXIST
If Not Defined IP[001] (
Echo %IPLIST% had no readable file content.
Echo Press any key to end this script.
Pause 1> NUL
GoTo :EOF
)
:VIEW_IP_VARIABLES
Set IP[
Pause & GoTo :EOF
The last line in both examples is for display purposes. If you're testing/running this script from within cmd.exe, you may omit it.
FOR /f "tokens=1*delims=:" %%a IN ('findstr /n /r ".*" "%filename1%"') DO set "IP%%a=%%b"
)
set IP
findstr reads the file in filename1 and produces a list of the format n:content of line n.
The for /f reads this list, and partitions it using 2 tokens - %%a gets the first token (1) and %%b the remainder of the line (*) using : as a delimiter.
So simply set the IP variables from there.
set ip displays all variables that start ip
Probability is that your file contains empty line(s) after the last IP. Your original code would have reported the LAST IP, not the FIRST as the value in firstip is overwritten on each iteration, so it would be cleared by being set to nothing when the empty lines are read.
The solution above would simply execute (eg) set "IP6=" under these circumstances, clearing the variable.
You could have obtained the first IP by using
if not defined firstip set "FirstIP=%%a"
I'm assuming a clean environment here - that is, that each batch you run includes a setlocal after the #echo off (which restores the initial environment when the batch finishes) and the variables used are known-empty.
Bonus:
changing the set command to
set "IP%%a=%%b"&if "%%b" neq "" set "ipmax=%%a"
would set ipmax to the number of the last non-empty line, as %%b is empty for an empty line.
The batch file could have following command lines:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "LOGFILE=%~dp0IPScript.log"
set "IPLIST=%~dp0IPLIST.txt"
set "AddressCount=0"
echo Script started>"%LOGFILE%"
for /F "delims==" %%I in ('set IP_Address_ 2^>nul') do set "%%I="
if exist "%IPLIST%" for /F "useback delims=" %%I in ("%IPLIST%") do (
set /A AddressCount+=1
call set "IP_Address_%%AddressCount%%=%%I"
)
if not %AddressCount% == 0 (
if %AddressCount% == 1 (
echo The IP address is:
) else echo The IP addresses are:
echo/
set IP_Address_
) >>"%LOGFILE%"
endlocal
The batch file first two command line define the execution environment which means:
Disable command echo mode.
Push current command extension state on stack and enable command extensions.
Push current delayed expansion state on stack and disable delayed environment variable expansion.
Push path of current directory on stack.
Push pointer to current list of environment variables on stack and create a copy of the entire current environment variables list to use next.
The third and fourth line define two environment variables with the name of the log file and the name of the IP address list file with full qualified file name. The file path of both files is defined as path of the directory containing the batch file referenced with %~dp0. This path always ends with \ and for that reason no additional backslash is needed on concatenating this path with the two file names.
The fifth line define the environment variable AddressCount with value 0.
The sixth line creates the log file in current directory with overwriting an already existing log file. There is no space left to redirection operator > as this space would be output by command ECHO and therefore written as trailing space also into the log file.
The first FOR command with option /F starts in background with %ComSpec% /c one more command process with the command line between ' appended as additional arguments. So executed is in background with Windows installed into C:\Windows:
C:\Windows\System32\cmd.exe /c set IP_Address_ 2>nul
Windows creates a copy of current list of environment variables for the command process started in background. The background command process runs command SET to output all environment variables with name, an equal sign and the string value assigned to the variable line by line of which name starts with IP_Address_. This output to handle STDOUT of background command process is captured by FOR respectively the command process which is processing the batch file. The error message output by SET on no environment variable define with a name starting with IP_Address_ is redirected from handle STDERR to device NUL to suppress this error message.
Read the Microsoft documentation about Using command redirection operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background.
FOR processes the captured output line by line after started background command process closed itself after execution of command SET. Empty lines are always ignored by FOR which can be ignored as there are no empty lines output by SET.
FOR would split up by default the current line into substrings using normal space and horizontal tab as delimiters. This default line splitting behavior is not wanted here. The option delims== defines the equal sign as string delimiter to split the line on = which is the character between variable name and variable value.
FOR would next ignore the line if the first substring would start with a semicolon which is the default end of line character. The command SET outputs only lines starting with IP_Address_ and for that reason the default eol=; can be kept in this case.
FOR assigns just the first substring to the specified loop variable I as tokens=1 is the default. That is exactly the wanted behavior in this case.
So FOR assigns one environment variable name starting with IP_Address_ to loop variable I and runs next the command SET to delete this environment variable in current list of environment variables of command process processing the batch file.
In other words the first FOR is for deletion of all environment variables of which name starts with IP_Address_ defined by chance outside the batch file.
The next line first checks if the file with the list of environment variables exists at all in directory of the batch file. In this case once again FOR is used to process lines, but this time read line by line from the specified list file instead of captured output of a background command process. The usage of " instead of ' with the option usebackq makes the difference.
There is used the option delims= to define an empty list of delimiters resulting in getting each non-empty line not starting with ; assigned completely to the specified loop variable I.
For each string assigned to loop variable I the current value of environment variable AddressCount is incremented by one using an arithmetic expression evaluated by command SET.
This value is used on next command line to define an environment variable of which name starts with IP_Address_ and has appended the current address count value with line read from file assigned to the environment variable.
There is usually used delayed expansion for such tasks on which the second command line in command block of second FOR loop would be:
set "IP_Address_!AddressCount!=%%I"
But the code above uses the alternative method with command call to parse set "IP_Address_%%AddressCount%%=%%I" a second time which was already modified to set "IP_Address_%AddressCount%=%I" before the IF condition left to FOR was executed at all.
The next IF condition checks if any line was read from the list file with the IP addresses. In this case first an information line is output depending on having read exactly one line from the file or more than one line. Then an empty line is output and last all environment variables of which name starts with IP_Address_ with = and the line (IP address) assigned to the environment variable. All this output is appended to the log file.
The last command restores previous execution environment which means:
Discard the current list of environment variables and pop from stack the pointer to initial list of environment variables resulting in restoring the initial list of environment variables. In other words all environment variables defined or modified by the batch file after command SETLOCAL in second command line are lost forever.
Pop path of current directory from stack and make this directory again the current directory. The current directory between setlocal and endlocal was not changed by the code between and so this does not matter here.
Pop delayed expansion state from stack and enable or disable delayed environment variable expansion accordingly to restore initial delayed expansion behavior.
Pop current command extension state from stack and enable or disable command extensions accordingly to restore initial command extension behavior.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
echo /?
endlocal /?
for /?
if /?
set /?
setlocal /?
See also:
Variables are not behaving as expected
How does the Windows Command Interpreter (CMD.EXE) parse scripts?
Microsoft's documentation for the Windows Commands
SS64.com - A-Z index of Windows CMD commands

How to not lose special characters when processing a text file in a bat?

I have this text document (txt1.txt):
&()[]{}^=;!'+,`~.mp3
¿¡áéíóú!.mp3
When processing it with a FOR command I lose characters like "^" and "!".
The bat file is as follows (it has two FOR commands that maybe can be simplified into just one, and the second one has an ECHO command at the end that I don't know if it can be implemented better):
#ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
CHCP 1252
SET TXTFILE1=txt1.txt
SET TXTFILE2=txt2.txt
(
FOR /F "usebackq delims=" %%I IN (%TXTFILE1%) DO (
SET LINE=%%I
ECHO !LINE:.mp3=!
)
) > %TXTFILE2%
SET LINENUMBER=1
SET TXTFILE3=txt3.bat.txt
FOR /F "usebackq eol=| delims=" %%J IN (%TXTFILE2%) DO (
ECHO SET TRACK!LINENUMBER!=%%J>> %TXTFILE3%
SET /A LINENUMBER+=1
)
ECHO EXIT /B>> %TXTFILE3%
ENDLOCAL
PAUSE > NUL | SET /P =Presione una tecla para salir . . . & ECHO(
EXIT
Use this code for the batch file:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceFile=txt1.txt"
set "OutputFile=txt2.txt"
set "LineNumber=0"
(
for /F usebackq^ delims^=^ eol^= %%I in ("%SourceFile%") do (
set "Line=%%I"
set /A LineNumber+=1
setlocal EnableDelayedExpansion
echo set TRACK!LineNumber!=!Line:.mp3=!
endlocal
)
) >"%OutputFile%"
endlocal
For an explanation of the FOR loop see my answer on How to read and print contents of text file line by line? Empty lines in source file are ignored by FOR which should be no problem here as it looks like the source file contains a list of MP3 file names.
The question does not contain an example content of source file and an example of expected content of output file. So the code was tested with a source file created by myself which are the lines as posted at How to read and print contents of text file line by line? with some lines with .mp3 appended and one line with ^ added.
If all lines end with .mp3 it would be better to use:
echo set TRACK!LineNumber!=!Line:~0,-4!
The line read from file is in this case output without the last four characters.
It is important to have delayed expansion NOT enabled on assigning the line read from file to environment variable Line. Otherwise this line is parsed by cmd.exe a second time as explained by How does the Windows Command Interpreter (CMD.EXE) parse scripts? On second parsing of SET LINE=%%I each ^ in line read from file is interpreted as escape character and each ! is interpreted as begin/end of an environment variable reference.
For that reason it is necessary to assign first the line read from file to environment variable Line while delayed expansion is disabled to avoid parsing the line before execution command SET by Windows command processor. Then delayed environment variable expansion is enabled which results in creating a copy of current list of environment variables, pushing current directory path on stack and pushing also current states of command extensions and delayed environment variable expansion on stack before enabling also delayed expansion. Then the line can be output with the additional text at beginning with line number and with case-insensitive removing all .mp3 occurrences from line. Finally command ENDLOCAL must be used to discard the copy of all environment variables, pop current directory path back from stack and pop also the states of command extensions and delayed expansion from stack and set those two features accordingly which means here disabling delayed expansion. Read this answer for details about the commands SETLOCAL and ENDLOCAL.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
for /?
set /?
setlocal /?

windows batch command nested variable

I have a requirement to use nested variables for creating a folder based on a environment variables.
Assume I have variables listed below:
%ABC_ASIA_LOCATION%
%ABC_EUROPE_LOCATION%
%ABC_US_LOCATION%
and I want to pass the country as variable like %ABC_%COUNTRY%_LOCATION%.
How do I achieve this in Windows utilizing batch scripting?
you have to enclose each variable into %:
set "ABC=ABC"
set "COUNTRY=EUROPE
set "LOCATION=MUNICH
echo %ABC%_%COUNTRY%_%LOCATION%
Result: ABC_EUROPE_MUNICH
Or if you just want Country as a variable, keeping the rest fixed:
echo ABC_%COUNTRY%_LOCATION
Result: ABC_EUROPE_LOCATION
or if you want the whole thing to be a variable (a variable name containing another variable), you have to use delayed expansion:
setlocal enabledelayedexpansion
set country=EUROPE
set "ABC_EUROPE_LOCATION=a town in southern Germany"
echo !ABC_%country%_LOCATION!
which gives you: a town in southern Germany
Note: setlocal has no effect outside of batchfiles, so delayed expansion works only:
- in batchfiles
- when the command prompt was started with delayed expansion enabled (cmd /v:on) (by default, the command prompt runs with delayed expansion disabled)
There are times when you need the nested variable to work inside a for loop, which already requires the !varname! syntax for the variable expansion. When this is the case, !ABC_%country%LOCATION!, will not work (reference Stephan's post on 9/6/2017 at 7:24). Neither will !ABC!country!_LOCATION!.
The following batch file demonstrates this. This is a somewhat contrived example to demonstrate the issue. In the subroutine, we can also set a variable to the nested value if you didn't want to do the work in the subroutine.
#echo off
setlocal enabledelayedexpansion
setlocal
set var1=value1
set var2=value2
set var3=value3
set var4=value4
set var5=value5
for %%A in (var1 var2 var3 var4 var5) do (
set varname=%%A
echo 1.This will not work: !varname!=!!varname!!
echo 2.This will not work: !varname!=%!varname!%
echo 3.This will not work: !varname!=!%varname%!
echo 4.This will not work: %varname%=%varname%
echo 5.This will not work: %varname%=%%varname%%
call:NestedVar %%A
call:getNestedVar new%%A %%A
echo new%%A=!new%%A!
echo.
echo.
)
goto:eof
:NestedVar
echo This will work: %1=!%1! (but only if setlocal enabledelayedexpansion is used)
goto:eof
:getNestedVar
REM Use: getNestedVar newVariableName varName
REM Will set newVariableName to the value of varName
echo Setting variable, %1=!%2!
set %1=!%2!
goto:eof

SET command expantion substrings

When using the SET command in command prompt, what does % and ! mean, for example
set VAR=before
if "%VAR%" == "before" (
set VAR=after
if "!VAR!" == "after" #echo If you see this, it worked)
set LIST=
for %i in (*) do set LIST=!LIST! %i
echo %LIST%
Notice how there's %i and !VAR! what does this mean, %i cant be a variable right? as variables are written out like %variable%.
Any ideas what these are?. Also is the (*) just a literal?
Regards, S
In normal cases you can access variable value by enclosing its name with % :
set var=a
echo %var%
As when there is composition of commands with & or a few commands are put in brackets the set will take effect after all of them are executed.Then you need delayed expansion to access your variable and to enclose it with !
setlocal enableDelayedExpansion
if exist c:\ (
set var2=a
echo !var2!
)
Take a more close look at SET command.
in for loops you have a special variables that works only in context of for command - a tokens that change its values on each iteration of the loop:
for /f "delims=" %%# in ('set') do echo %%#
here are the letters that you can use as tokens.And be careful - you need to use double % in a script and a single in command prompt.
There's one more type of variables that has a % only at the beginning - arguments passed to the script (or a subroutine) - accessible with numbers (or rather digits) - from %0 to %9 where %0
is the name of the script itself.

Resources