echo-ing a variable into a file - batch-file

I am trying to make a simple statistic program which simply counts how many times it's been runned. The problem occurs when I am echo-ing the variable of result of times onto the tracking-file, which are greater than 1. Is it impossible to echo a variable onto a file? What am I missing? :/
if not exist statistic_files (
mkdir statistic_files
)
cd statistic_files
if exist %username%-use_tracking (
FOR /F %%G IN (%username%-use_tracking) DO set /A uses=%%G+1
:: THE PROBLEM IS BELOW
echo %uses% > %username%-use_tracking
cd ..
)
if not exist %username%-use_tracking (
echo 1 > %username%-use_tracking
cd ..
)

Your code is failing when the file already exists because you are setting a variable value and later accessing the value within the same parenthesized code block; %uses% is expanded when the line is parsed, and the entire code block is parsed all at once. So the value you are echoing is the value that existed before the FOR loop is executed - not what you want.
You could solve the problem by enabling delayed expansion using setlocal enableDelayedExpansion, and then using !uses! instead of %uses%. Type help set from a command prompt for more information. Start reading with the paragraph that begins "Finally, support for delayed environment variable expansion has been added..." about halfway through the help.
But there is a simpler way that avoids the need for delayed expansion. You only need to set the value within the IF block. You can access it later outside of the IF block.
There is one other issue that you are currently avoiding, but you should be aware of: 1>filename and >filename do the same thing - they are an instruction to redirect standard output (stdout) to a file. 1 is the id of stdout, and it is the default when a number is not explicitly given. 2>filename redirects standard errror (stderr) to a file. You are avoiding interpretation of the number as the stream id because you have a space between the number and the >. But if you are not careful, you will someday not have a space and be confused as to why the number is not printing. You can avoid the problem by putting the redirection at the front instead of at the end. >filename echo %uses%
So here is a complete working solution.
#echo off
setlocal
if not exist statistic_files mkdir statistic_files
cd statistic_files
set "file=%username%-use_tracking"
set "uses=1"
if exist %file% for /f %%G IN (%file%) do set /A uses=%%G+1
>%file% echo %uses%

Testing your current file (just by removing the block at the top that creates the folder, so that it outputs to my current directory, the two cd .. lines, and adding set username=ken at the top) produces:
The correct content (a single line with 1) the first time.
A file with the single line ECHO is on the second time.
An error message the third time.
You're getting that output because ECHO is on, and the second run is ECHOing that setting the second time the batch file is run.
You need to turn echo off at the top of your batch file. (This doesn't prevent using the echo command; it just prevents your batch file itself from being output.)
This works for me (making the changes I mentioned above):
#echo off
set username=ken
if exist %username%-use_tracking (
FOR /F %%G IN (%username%-use_tracking) DO set /A uses=%%G+1
:: THE PROBLEM IS BELOW
echo %uses% > %username%-use_tracking
)
if not exist %username%-use_tracking (
echo 1 > %username%-use_tracking
)
The results were:
The correct content (a single line with 1) the first time.
A file with the single line 2 the second time.
A file with the single line 3 the third time. (And so forth with more runs.)
If you're wanting to keep every line in the file, change the first echo %uses% > %username%-use_tracking to echo %uses% > %username%-use_tracking (note the double >>) instead. One > means overwrite, two means append to the end of current content.

Your problem is directly related to Delayed variable Expansion. To solve it, insert this line at beginnng of your program:
setlocal EnableDelayedExpansion
and enclose the variable that was modified inside an IF block in exclamation marks instead percents:
echo !uses! > %username%-use_tracking
For further details, seek for "Delayed Expansion" in this forum; there are plenty answers on the topic, like this one:
Set the variable to another variable in the for statement

Use >> instead of > for redirect (append mode).
Use absolute path for log file, instead of relative path, if you are going to change the directory in between.

Ok, I have realised that for command affects variables in a strange way and I have to use delayed expansion. Thanks everyone for stating these. I have managed to make it work properly, exactly how I wanted it, here it is :
#echo off
setlocal EnableDelayedExpansion
if not exist statistic_files (
mkdir statistic_files
cd statistic_files
goto skip
)
cd statistic_files
:skip
set "file=%username%-use_tracking"
set "uses=1"
if not exist %file% (
>%file% echo 1
cd ..
)
if exist %file% (
for /f %%G IN (%file%) do set /A uses=%%G+1
>%file% echo !uses!
cd ..
)

you use single >
ie.: echo "Bla" > file.xyz
single > just overwrites anything in the file
try >>
echo "Blabla" >> file.xyz
double >> appends content at the end of the file

Related

Concatenated text file output from single ECHO command gets characters inserted into string printed a second time after expected output

I'm trying to create a batch file to insert a string from a .txt file at a specific place inside a string in 225 batch files - i.e., inserted into one line in the file at a specific place - but this question concerns the inserting part, and not the loop part, so I've left out the latter in my code example. It's also currently just displaying the text on-screen; not actually writing it to files.
The target files are a bunch of launch .bat files used for running a game server cluster using a tool, so I will have to leave each of them with the same names as they start with (Start XXYY.bat). They contain something along these lines:
start /high ShooterGame\Binaries\Win64\ShooterGameServer.exe Ocean?ServerX=0?ServerY=0?AltSaveDirectoryName=0000?ServerAdminPassword=1234?MaxPlayers=50?ReservedPlayerSlots=25?QueryPort=50002?Port=5002?SeamlessIP=192.168.1.225?RCONEnabled=true?RCONPort=28450 -log -server -NoBattlEye
exit
Where the ServerX, ServerY, AltSaveDirectoryNamen and all three Port settings are unique to each server, so these will have to remain unchanged.
I need to add several more settings, from another .txt file in the final version, but for this example I will just put the additions (the word INSERT added after the ReservedPlayerSlots setting, while keeping each setting divided by question marks) directly into this script.
My code is actually doing exactly what I want it to, but unfortunately it doesn't stop at that point, and decides to append more text than I wanted; specifically, everything I add to the ECHO command which is not a variable name.
To clarify, I get the exact output that I want... Plus the unwanted addition of a bunch of question marks and the word INSERT, which apparently come from my ECHO command, but I just have no idea why they get re-added.
My knowledge of batch scripting is fairly limited, so there might well be something basic that I've overlooked.
I've tried replacing the question marks in the output (which are required to be questions marks in the final version) with normal letters instead, but it doesn't change the behaviour; they were still appended to the expected output, just like the question marks they replaced.
#ECHO OFF
SET FileNum=0000
REM I will have the code loop through 225 files (0000-1414) in the final version, but for test purposes I just set it to one single file number manually here.
SET FileName=Start %FileNum%.bat
REN "%FileName%" temp.txt
FOR /F "tokens=1,2,3,4,5,6,7,8,9,10,11,12 delims=?" %%a IN (temp.txt) DO (
ECHO %%a?%%b?%%c?%%d?%%e?%%f?%%g?INSERT?%%h?%%i?%%j?%%k?%%l
)
REN temp.txt "%FileName%"
I expect this code to output this:
start /high ShooterGame\Binaries\Win64\ShooterGameServer.exe Ocean?ServerX=0?ServerY=0?AltSaveDirectoryName=0000?ServerAdminPassword=1234?MaxPlayers=50?ReservedPlayerSlots=25?INSERT?QueryPort=50002?Port=5002?SeamlessIP=192.168.1.225?RCONEnabled=true?RCONPort=28450 -log -server -NoBattlEye
exit
But what I am getting is this:
start /high ShooterGame\Binaries\Win64\ShooterGameServer.exe Ocean?ServerX=0?ServerY=0?AltSaveDirectoryName=0000?ServerAdminPassword=1234?MaxPlayers=50?ReservedPlayerSlots=25?INSERT?QueryPort=50002?Port=5002?SeamlessIP=192.168.1.225?RCONEnabled=true?RCONPort=28450 -log -server -NoBattlEye
exit???????INSERT?????
Which is the expected output, but with the unexpected re-addition of every symbol in the ECHO command which did not designate a variable at the end of the output (in this case ???????INSERT?????), just after the exit.
I'm stumped... I hope someone has an idea what I'm doing wrong here.
Okay, I applied the idea that aschipfl provided, and it seems to work now.
The IF NOT "%%b"=="" line seems to have done the trick, after I added the final line with the exit using another ECHO. My full script (including loop and write to file) is now like this:
#ECHO OFF
SETLOCAL EnableDelayedExpansion
SET "Insert=SettingOne=True?SettingTwo=False?SettingThree=1.000000"
FOR /l %%x IN (0, 1, 14) DO (
FOR /l %%y IN (0, 1, 14) DO (
IF %%x LSS 10 (SET XNum=0%%x) ELSE (SET XNum=%%x)
IF %%y LSS 10 (SET YNum=0%%y) ELSE (SET Ynum=%%y)
SET "FileNum=!XNum!!YNum!"
SET "FileName=Start !FileNum!.bat"
ECHO Filename: !FileName!
REN "!FileName!" temp.txt
(
FOR /F "tokens=1-12 delims=?" %%a IN (temp.txt) DO (
IF NOT "%%b"=="" (
ECHO %%a?%%b?%%c?%%d?%%e?%%f?%%g?%Insert%?%%h?%%i?%%j?%%k?%%l
ECHO exit
)
)
) >edited.txt
REN edited.txt "!FileName!"
DEL /q temp.txt
ECHO has been updated
)
)
This is now working exactly as intended.
It's quite possible that there is a more elegant way of doing this, and I am cartain that there is a way of making this more general and less hard-coded, but it's good enough for my purposes.
I thank you for your help!

A script that counts and prints every ocurrence of not any file inside a common subfolder in a specific path

Although I'm really a newbie in this field, I want to accomplish a task in batch scripting: There is a determinate folder of company contracts in a determinate path, each of this folders (approx. 400) has a common folder (2016) where there might be a file indicating there has been an inspection in this year. What i want is to print every company folder that has not any file in the common 2016 folder and a count of the times this happens.
This is what i have (and does not work at all):
set c=0
for %i /d in (*) do
for %j in ($%i\2016\*) do
if (%j==NUL) then (#echo $%i c+=1 echo %c)`
If you just want to know if there is a file in the 2016 directory you can do this:
#echo off
SetLocal EnableDelayedExpansion
set count=0
for %%i /d in (*) do (
REM first unset variable
set files=
for %%j in (%%i\2016\*) do (
REM will set variable each time a file is encountered
set files=present
)
if not DEFINED files (
REM No files in directory 2016
echo %%i
set /a count+=1
echo !count!
)
)
EndLocal
exit /b 0
I don't see why you use $ before each %i. If you execute this code from the command line use one % for the loop variables i and j. But in a batch-script you'll have to use two of them (%%i, %%j).
Another thing, c+=1 won't work except if you use set /a.
I used delayed expansion because each block code ( between (...)) is parsed as one single command (as if it was all on one line with && between the commands inside the block) and you can't just assign a new value to a variable and read that new value in the same command. That's also the reason why I use !count! instead of %count% (which will give the value before the block). If you'd rather not use delayed expansion, remove the SetLocal EnableDelayedExpansion and replace echo !count! with call echo %%count%% (is another way to read a new value in the same command)
Also, be aware that each echo will end its output with a carriage retur and a newline. So each echo will result in a new line of output.

Echo not working properly inside IF ELSE structure

I have had plenty of problems when moving lines inside IF/ELSE structure. Code below does not print
echo %VALUE1%;%VALUE2:~0,2%;%VALUE3%;%VALUE4%;%VALUE5%
to file. Instead of that values are printed to console and last character is dropped. What is the problem?
#echo off
setlocal enabledelayedexpansion
SET ENABLED_X=1
SET FILE=test.txt
SET VALUE1=23,5
SET VALUE2=34,1
SET VALUE3=0,45
SET VALUE4=3,33
SET VALUE5=3,5
IF /I %ENABLED_X%==0 (
echo %VALUE1%;%VALUE2%;%VALUE3%;%VALUE4%>>%FILE%
echo NOT ENABLED
) ELSE (
echo %VALUE1%;%VALUE2:~0,2%;%VALUE3%;%VALUE4%;%VALUE5%>>%FILE%
echo %VALUE1%;%VALUE2:~0,2%;%VALUE3%;%VALUE4%;%VALUE5%
echo ENABLED
)
The part 5>>test.txt will be interpreted as redirection. Normally it's used as 1>>file or 2>>file to redirect standard output and error output, respectively.
Use
>>%FILE% echo %VALUE1%;%VALUE2:~0,2%;%VALUE3%;%VALUE4%;%VALUE5%
instead. Doing the redirection at the beginning of the line will never let it interfere with something else.
Note: without quotes, %FILE% is ok. You might run into trouble when using spaces in the file name.
Just place a single space before both of your >>
or
(echo %VALUE…)>>%FILE%

Batch - redirecting an ECHOed SET definition line into file will show the line instead of writing it into file

I wrote the following:
#ECHO OFF
SET v1old=4
SET v2old=0
SET v3old=7453
SET v1new=83
SET v2new=645
SET v3new=2
SET bug=SET
ECHO #ECHO OFF ^& SETLOCAL>>newupdate.bat
ECHO REM .>>newupdate.bat
ECHO REM version von dolphin>>newupdate.bat
ECHO %bug% v1old=%v1new%>>newupdate.bat
ECHO %bug% v2old=%v2new%>>newupdate.bat
ECHO %bug% v3old=%v3new%>>newupdate.bat
ECHO %bug% bug=%bug%
PAUSE
EXIT
The following line will be shown in console instead of beeing written into the bat file:
ECHO %bug% v3old=%v3new%>>newupdate.bat
The variable v3new stores a value from 0-9 if I let them store something other like chars, signs or values with more then 1 digit it will work...
I want that the script mutates himself where only the first lines will change.
So I want to write the first lines to a new file...
Why does it not work, is that a bug or do I do something wrong?
Solutions
The answer by Seth McCauley works fine for the echo-ed set lines.
An alternative and more generic solution is to put every echo within parentheses like this, hence the original set string is redirected without any modification:
(ECHO %bug% v3old=%v3new%)>>newupdate.bat
Another yet worse possibility is to insert a single SPACE before redirection >/>>; this prevents the line from being displayed in the console window, but the SPACE is redirected as well (and, when newupdate.bat is executed, it will be assigned to the variable value as well).
Root Cause
The problem is the combination of characters that appear in the failing echo line (the third one here):
ECHO %bug% v1old=%v1new%>>newupdate.bat
ECHO %bug% v2old=%v2new%>>newupdate.bat
ECHO %bug% v3old=%v3new%>>newupdate.bat
Remove #echo off from the top of your batch script temporarily and you will see what command line is echoed to the console respectively:
ECHO SET v1old=83 1>>newupdate.bat
ECHO SET v2old=645 1>>newupdate.bat
ECHO SET v3old= 2>>newupdate.bat
The console shows the unwanted response, which is not written to newupdate.bat unintentionally:
SET v3old=
This is because of the character substring =2>> in the expanded and echoed command. Why:
= acts as a separator, like also SPACE, ,, ;.
Because of the preceding separator =, 2>> is treated as the redirection operator.
2, since it is a one-digit number immediately preceding >>, is taken as a handle for redirection, where 2 means STDERR (1 is STDOUT, the default for >/>>; 0 is STRIN, 3 - 9 are undefined).
All this means that STDERR is redirected into newupdate.bat rather than the echo-ed line which appears at STDOUT (handle 1). STDERR carries no data here so nothing goes to the file.
For the other lines, as at least one of the above listed conditions is violated, redirection is not modified unintentionally, so >> (same as 1>>) is applied, so STDOUT is redirected into the file and STDERR goes to the console but is empty anyway.
So STDOUT carries the following data with respect to the above three lines:
SET v1old=83
SET v2old=645
Note that without redirection, both STDOUT and STDERR were passed to the console as per default.
Reference this resource for the redirection syntax and this post for a great explanation of redirection.
Conclusion
Since there is a separator (one of SPACE, ,, ;, =) followed by a variable string portion followed by redirection signs >>, it could happen that unintended redirections occur, when the said central string becomes a single decimal figure.
All of the solutions presented on top of this answer (including the referenced one) work because there is a character inserted in between the redirection mark >> and the preceding string portion.
Here are two modern methods to echo into a file without trailing spaces:
Note the first redirection only has one > to create or overwrite the file.
#ECHO OFF
SET v1old=4
SET v2old=0
SET v3old=7453
SET v1new=83
SET v2new=645
SET v3new=2
SET bug=SET
>newupdate.bat ECHO #ECHO OFF ^& SETLOCAL
>>newupdate.bat ECHO REM .
>>newupdate.bat ECHO REM version von dolphin
>>newupdate.bat ECHO %bug% v1old=%v1new%
>>newupdate.bat ECHO %bug% v2old=%v2new%
>>newupdate.bat ECHO %bug% v3old=%v3new%
ECHO %bug% bug=%bug%
PAUSE
EXIT
This method is very useful, but ) need to be escaped to ^) also
#ECHO OFF
SET v1old=4
SET v2old=0
SET v3old=7453
SET v1new=83
SET v2new=645
SET v3new=2
SET bug=SET
(
ECHO #ECHO OFF ^& SETLOCAL
ECHO REM .
ECHO REM version von dolphin
ECHO %bug% v1old=%v1new%
ECHO %bug% v2old=%v2new%
ECHO %bug% v3old=%v3new%
)>newupdate.bat
ECHO %bug% bug=%bug%
PAUSE
EXIT
The batch echo command has a variety of issues displaying certain content. Putting double quotes around the SET statements will resolve the issue you are experiencing. You may also want to change your first file redirection to use > instead of >>, so that the batch file is overwritten each time instead of appended to. Here is the updated code:
#ECHO OFF
SET "v1old=4"
SET "v2old=0"
SET "v3old=7453"
SET "v1new=8"
SET "v2new=645"
SET "v3new=2"
ECHO #ECHO OFF ^& SETLOCAL>newupdate.bat
ECHO REM .>>newupdate.bat
ECHO REM version von dolphin>>newupdate.bat
ECHO SET "v1old=%v1new%">>newupdate.bat
ECHO SET "v2old=%v2new%">>newupdate.bat
ECHO SET" v3old=%v3new%">>newupdate.bat
PAUSE
EXIT
This is happening because v3new is 2. So you are directing STDERR to newupdate.bat. Easy way for you to see that is to temporarily comment out the #ECHO OFF and you will see that the line in question expands to
ECHO SET v3old= 2>>newupdate.bat
#Seth has good suggestions but you will still have the problem. Inserting a space between > and newupdate.bat in each case would solve the problem.

Batch file include external file for variables

I have a batch file and I want to include an external file containing some variables (say configuration variables). Is it possible?
Note: I'm assuming Windows batch files as most people seem to be unaware that there are significant differences and just blindly call everything with grey text on black background DOS. Nevertheless, the first variant should work in DOS as well.
Executable configuration
The easiest way to do this is to just put the variables in a batch file themselves, each with its own set statement:
set var1=value1
set var2=value2
...
and in your main batch:
call config.cmd
Of course, that also enables variables to be created conditionally or depending on aspects of the system, so it's pretty versatile. However, arbitrary code can run there and if there is a syntax error, then your main batch will exit too. In the UNIX world this seems to be fairly common, especially for shells. And if you think about it, autoexec.bat is nothing else.
Key/value pairs
Another way would be some kind of var=value pairs in the configuration file:
var1=value1
var2=value2
...
You can then use the following snippet to load them:
for /f "delims=" %%x in (config.txt) do (set "%%x")
This utilizes a similar trick as before, namely just using set on each line. The quotes are there to escape things like <, >, &, |. However, they will themselves break when quotes are used in the input. Also you always need to be careful when further processing data in variables stored with such characters.
Generally, automatically escaping arbitrary input to cause no headaches or problems in batch files seems pretty impossible to me. At least I didn't find a way to do so yet. Of course, with the first solution you're pushing that responsibility to the one writing the config file.
If the external configuration file is also valid batch file, you can just use:
call externalconfig.bat
inside your script. Try creating following a.bat:
#echo off
call b.bat
echo %MYVAR%
and b.bat:
set MYVAR=test
Running a.bat should generate output:
test
Batch uses the less than and greater than brackets as input and output pipes.
>file.ext
Using only one output bracket like above will overwrite all the information in that file.
>>file.ext
Using the double right bracket will add the next line to the file.
(
echo
echo
)<file.ext
This will execute the parameters based on the lines of the file. In this case, we are using two lines that will be typed using "echo". The left bracket touching the right parenthesis bracket means that the information from that file will be piped into those lines.
I have compiled an example-only read/write file. Below is the file broken down into sections to explain what each part does.
#echo off
echo TEST R/W
set SRU=0
SRU can be anything in this example. We're actually setting it to prevent a crash if you press Enter too fast.
set /p SRU=Skip Save? (y):
if %SRU%==y goto read
set input=1
set input2=2
set /p input=INPUT:
set /p input2=INPUT2:
Now, we need to write the variables to a file.
(echo %input%)> settings.cdb
(echo %input2%)>> settings.cdb
pause
I use .cdb as a short form for "Command Database". You can use any extension.
The next section is to test the code from scratch. We don't want to use the set variables that were run at the beginning of the file, we actually want them to load FROM the settings.cdb we just wrote.
:read
(
set /p input=
set /p input2=
)<settings.cdb
So, we just piped the first two lines of information that you wrote at the beginning of the file (which you have the option to skip setting the lines to check to make sure it's working) to set the variables of input and input2.
echo %input%
echo %input2%
pause
if %input%==1 goto newecho
pause
exit
:newecho
echo If you can see this, good job!
pause
exit
This displays the information that was set while settings.cdb was piped into the parenthesis. As an extra good-job motivator, pressing enter and setting the default values which we set earlier as "1" will return a good job message.
Using the bracket pipes goes both ways, and is much easier than setting the "FOR" stuff. :)
So you just have to do this right?:
#echo off
echo text shizzle
echo.
echo pause^>nul (press enter)
pause>nul
REM writing to file
(
echo XD
echo LOL
)>settings.cdb
cls
REM setting the variables out of the file
(
set /p input=
set /p input2=
)<settings.cdb
cls
REM echo'ing the variables
echo variables:
echo %input%
echo %input2%
pause>nul
if %input%==XD goto newecho
DEL settings.cdb
exit
:newecho
cls
echo If you can see this, good job!
DEL settings.cdb
pause>nul
exit
:: savevars.bat
:: Use $ to prefix any important variable to save it for future runs.
#ECHO OFF
SETLOCAL
REM Load variables
IF EXIST config.txt FOR /F "delims=" %%A IN (config.txt) DO SET "%%A"
REM Change variables
IF NOT DEFINED $RunCount (
SET $RunCount=1
) ELSE SET /A $RunCount+=1
REM Display variables
SET $
REM Save variables
SET $>config.txt
ENDLOCAL
PAUSE
EXIT /B
Output:
$RunCount=1
$RunCount=2
$RunCount=3
The technique outlined above can also be used to share variables among multiple batch files.
Source: http://www.incodesystems.com/products/batchfi1.htm
Kinda old subject but I had same question a few days ago and I came up with another idea (maybe someone will still find it usefull)
For example you can make a config.bat with different subjects (family, size, color, animals) and apply them individually in any order anywhere you want in your batch scripts:
#echo off
rem Empty the variable to be ready for label config_all
set config_all_selected=
rem Go to the label with the parameter you selected
goto :config_%1
REM This next line is just to go to end of file
REM in case that the parameter %1 is not set
goto :end
REM next label is to jump here and get all variables to be set
:config_all
set config_all_selected=1
:config_family
set mother=Mary
set father=John
set sister=Anna
rem This next line is to skip going to end if config_all label was selected as parameter
if not "%config_all_selected%"=="1" goto :end
:config_test
set "test_parameter_all=2nd set: The 'all' parameter WAS used before this echo"
if not "%config_all_selected%"=="1" goto :end
:config_size
set width=20
set height=40
if not "%config_all_selected%"=="1" goto :end
:config_color
set first_color=blue
set second_color=green
if not "%config_all_selected%"=="1" goto :end
:config_animals
set dog=Max
set cat=Miau
if not "%config_all_selected%"=="1" goto :end
:end
After that, you can use it anywhere by calling fully with 'call config.bat all' or calling only parts of it (see example bellow)
The idea in here is that sometimes is more handy when you have the option not to call everything at once. Some variables maybe you don't want to be called yet so you can call them later.
Example test.bat
#echo off
rem This is added just to test the all parameter
set "test_parameter_all=1st set: The 'all' parameter was NOT used before this echo"
call config.bat size
echo My birthday present had a width of %width% and a height of %height%
call config.bat family
call config.bat animals
echo Yesterday %father% and %mother% surprised %sister% with a cat named %cat%
echo Her brother wanted the dog %dog%
rem This shows you if the 'all' parameter was or not used (just for testing)
echo %test_parameter_all%
call config.bat color
echo His lucky color is %first_color% even if %second_color% is also nice.
echo.
pause
Hope it helps the way others help me in here with their answers.
A short version of the above:
config.bat
#echo off
set config_all_selected=
goto :config_%1
goto :end
:config_all
set config_all_selected=1
:config_family
set mother=Mary
set father=John
set daughter=Anna
if not "%config_all_selected%"=="1" goto :end
:config_size
set width=20
set height=40
if not "%config_all_selected%"=="1" goto :end
:end
test.bat
#echo off
call config.bat size
echo My birthday present had a width of %width% and a height of %height%
call config.bat family
echo %father% and %mother% have a daughter named %daughter%
echo.
pause
Good day.
The best option according to me is to have key/value pairs file as it could be read from other scripting languages.
Other thing is I would prefer to have an option for comments in the values file - which can be easy achieved with eol option in for /f command.
Here's the example
values file:
;;;;;; file with example values ;;;;;;;;
;; Will be processed by a .bat file
;; ';' can be used for commenting a line
First_Value=value001
;;Do not let spaces arround the equal sign
;; As this makes the processing much easier
;; and reliable
Second_Value=%First_Value%_test
;;as call set will be used in reading script
;; refering another variables will be possible.
Third_Value=Something
;;; end
Reading script:
#echo off
:::::::::::::::::::::::::::::
set "VALUES_FILE=E:\scripts\example.values"
:::::::::::::::::::::::::::::
FOR /F "usebackq eol=; tokens=* delims=" %%# in (
"%VALUES_FILE%"
) do (
call set "%%#"
)
echo %First_Value% -- %Second_Value% -- %Third_Value%
While trying to use the method with excutable configuration
I noticed that it may work or may NOT work
depending on where in the script is located the call:
call config.cmd
I know it doesn't make any sens, but for me it's a fact.
When "call config.cmd" is located at the top of the
script, it works, but if further in the script it doesn't.
By doesn't work, I mean the variable are not set un the calling script.
Very very strange !!!!

Resources