Thomas Morse
Thomas Morse

Reputation: 59

trying to read in data and store it in a variable in batch

I'm trying to get data from a file and store it in a variable for later use in my batch file.

Code example

SETLOCAL EnableDelayedExpansion
:: Reading a line in from a file
for /f "tokens=2 delims=:" %%a in (input.txt) do (
SET "TEMP=%%a"
echo %%a
echo %TEMP%
REM I want TEMP to be set to the value of %%a after the first character
SET "TEMP=%%a:~1%"
)
ENDLOCAL

Data inside input.txt:

O: Dracorex Hivelord, VE, SG, OV, AW, NM, Living Dam, BR, EV, VE #2
R: Silus the Corrupt, EV, OS, EB, VE, BR, DH, BV

The result that I'm getting when testing to see if its working the way I want:

 SET temp=! Silus the Corrupt, EV, OS, EB, VE, BR, DH, BV!
 ENDLOCAL   & SET TEMP=C:\Users\THOMAS~1\AppData\Local\Temp
 echo  Silus the Corrupt, EV, OS, EB, VE, BR, DH, BV
 echo C:\Users\THOMAS~1\AppData\Local\Temp

Can't seem to find out what I'm doing wrong.

Another part that I'm trying to do

for /f "tokens=*" %%a in (input2.txt) do (
SET STR=%%%a:~26, 6%
call :GetWinChance %STR%
)

Data inside input2.txt

Optimized Deck: 9 units: 86.6667: Dracorex Hivelord, Astral Strutter, Stonewall Garrison, Living Dam, Barracus Redeemed, Vile Emergence #2, Oluth's Volition, Nettle Miscreant, Atomic Wardriver
Optimized Deck: 10 units: 100%: Dracorex Hivelord, Astral Strutter, Stonewall Garrison, Living Dam, Barracus Redeemed, Vile Emergence #2, Oluth's Volition, Nettle Miscreant, Atomic Wardriver

and the results that I'm getting:

E:\Programs\Tyrant Unleashed Optimizer>(
SET STR=%~26, 6
 call :GetWinChance
)

Going to try and explain what I want

I want it so I can have in the first code sample that I get

Dracorex Hivelord, VE, SG, OV, AW, NM, Living Dam, BR, EV, VE #2
Silus the Corrupt, EV, OS, EB, VE, BR, DH, BV

as the values to be used while in the for loop.

In the second code sample I want to get it so I have the win chance which is contained in the 6 characters after the first 26 like so:

"86.666"
" 100: "

so I can use my function :GetWinChance (which I've tested with a variable that is set to a string to interpret the text into a percentage of win.

Upvotes: 1

Views: 127

Answers (3)

Magoo
Magoo

Reputation: 80013

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
:: Reading a line in from a file
for /f "tokens=2 delims=:" %%a in (q36074967.txt) do (
 SET "VAR=%%a"
 echo "%%a"
 echo parse... "%VAR%" delayed... "!VAR!"
 REM I want VAR to be set to the value of %%a after the first character
 SET "VAR=!VAR:~1!"
 echo VAR becomes "!VAR!"
)
ECHO ==========================
SET "var="
for /f "tokens=1* delims=:" %%a in (q36074967.txt) do (
 SET "VAR=%%b"
 echo "%%b"
 echo parse... "%VAR%" delayed... "!VAR!"
 REM I want VAR to be set to the value of %%b after the first character
 SET "VAR=!VAR:~1!"
 echo VAR becomes "!VAR!"
)
ECHO ==========================
SET "var="
for /f "tokens=1* delims=:" %%a in (q36074967.txt) do (
 for /f "tokens=*" %%c in ("%%b") do (
 SET "VAR=%%c"
  echo metab="%%b"
  echo metac="%%c"
  echo parse... "%VAR%" delayed... "!VAR!"
 )
)

ENDLOCAL

GOTO :EOF

I used a file named q36074967.txt containing your data for my testing.

So - problems:

First, don't use temp as a variablename (case is irrelevant) because windows' utilities use the OS-supplied value of temp to refer to a temporary directory. Exactly the same remark goes for tmp - some use one, some use t'other.

Other "magic" variables of note are random, time, date, cd and path. They have special meanings and are best controlled by cmd.

You can't substring a metavariable (loop-control variable) - you must put it into a standard environment variable, and substring that.

%var% always refers to the parse-time value of the variable - in fact, %var% is replaced by its value by the parser and then the logical line is executed. A logical line may be many physical lines including any code blocks - a series of statements enclosed in parentheses.

IOW, a logical line would be a for keyword ip to the line with the very last ) that is in its scope.

Since you have invoked delayedexpansion, then !var! refers to the run-time value, that is the value as it changes within the loop.

So - here's three different approaches. The last one uses the interesting property that "tokens=*" alone strips leading separators (like spaces) from the string.

I'm concerned that you've used endlocal. The downside of endlocal is that it discards all changes made to the environment since its setlocal - so if you want those changes to stick, you need to take appropriate measures.

If a batch reaches physical end-of-file, it executes an implicit endlocal.

Upvotes: 1

RGuggisberg
RGuggisberg

Reputation: 4750

This will do what you want other than "store it in a variable for later use". What do you mean by that? If "later use" is within the FOR loop, then you can just use %%b. If "later use" is outside the FOR loop, then your logic is flawed, as you have 1 variable and 2 lines; so the last line would be the only one in the variable if used outside the loop.

for /f "tokens=1* delims=: " %%a in (input.txt) do echo(%%b

If you want to get the results you expected, try this. Notice that this method retains the space after the : (not sure which way you want that).

:: Reading a line in from a file
SETLOCAL ENABLEDELAYEDEXPANSION
for /f "tokens=1* delims=: " %%a in (input.txt) do (
   SET "temp=%%b"
   echo(%%b
   echo(!TEMP!
)
ENDLOCAL

Upvotes: 0

user6017774
user6017774

Reputation:

REM Remove faulty comment line
REM :: Reading a line in from a file

SETLOCAL EnableDelayedExpansion


for %f "tokens=2 delims=:" %%a in (input.txt) do (
SET temp=%%a

REM Pointless command set something to it's self
REM SET TEMP=%temp%

echo %%a
echo !TEMP!
)

See inline comments. See where I've moved your !. See where setlocal has been moved to.

For help see for /?, rem /?, and setlocal /?.

Upvotes: 0

Related Questions