1

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.

  • You have 2 lines and numerous CSVs in the input file. Your question does not describe what data you want to store in the variable. – RGuggisberg Mar 18 '16 at 02:22
  • CSVs? I'm trying to get the data that is past the ":" in each line into a variable to use later in my batch. Its currently giving me the C:\Users\Thomas~1\AppData\Local\Temp when I try and store it to a variable to use. – Thomas Morse Mar 18 '16 at 02:30
  • CSV - Comma Separated Values – RGuggisberg Mar 18 '16 at 03:00
  • Ok. Well I want to read in everything like I said past the ":" in the text files per line and store it in TEMP. – Thomas Morse Mar 18 '16 at 03:02
  • You got an answer that works. Your problem is you are using endlocal before using it. –  Mar 18 '16 at 03:16

3 Answers3

1
@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.

Magoo
  • 77,302
  • 8
  • 62
  • 84
  • `tmp` is the Windows temp dir and `temp` is the dos temp dir. –  Mar 18 '16 at 08:02
  • @Noodles, there is not really a difference between `tmp` and `temp` as it depends on the application which of the two variables is used... – aschipfl Mar 18 '16 at 10:25
  • Well there is and I just told what it was. –  Mar 18 '16 at 15:29
  • @Noodles, you might be interested in [this post](http://stackoverflow.com/q/581966)... – aschipfl Mar 18 '16 at 21:18
  • 1
    MS-DOS 2.0 introduced the ability to pipe the output of one program as the input of another. Since MS-DOS was a single-tasking operating system, this was simulated by redirecting the first program’s output to a temporary file and running it to completion, then running the second program with its input redirected from that temporary file. Now all of a sudden, MS-DOS needed a location to create temporary files! For whatever reason, the authors of MS-DOS chose to use the TEMP variable to control where these temporary files were created. –  Mar 18 '16 at 21:53
  • 1
    Windows went through a similar exercise, but for whatever reason, the original authors of the Get­Temp­File­Name function chose to look for TMP before looking for TEMP. https://blogs.msdn.microsoft.com/oldnewthing/20150417-00/?p=44213 –  Mar 18 '16 at 21:54
  • @aschipfl Not very likely I'd rely on anything at SO. People here don't read documentation therefore their opinions aren't worth much. –  Mar 18 '16 at 21:58
0
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 /?.

  • Still getting the same issue. %%a will show what I want TEMP to contain, while TEMP is set for some reason to C:\Users\THOMAS~1\AppData\Local\Temp – Thomas Morse Mar 18 '16 at 02:42
  • Also from what I had seen when I looked up how to do comments, :: can be substituted for REM, aside from inside ()'s. – Thomas Morse Mar 18 '16 at 02:47
  • temp is a system variable. Type `set` and `set /?` for a list of variables. However you can override it but `SetLocal` makes it a local var, so it will revert to it's system value after `EndLocal`. –  Mar 18 '16 at 02:48
  • Also I'm not sure where you are getting typing set or set /? for anything. I'm not sure what you are using, but I'm using Notepad++. – Thomas Morse Mar 18 '16 at 02:51
  • No it can't. You are setting a label of `:`. Don't read sites of idiots. They are observing behaviour that is unintended. But we are programmers, we use the contract specified in the documentation. Then it will work forever. –  Mar 18 '16 at 02:51
0

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
RGuggisberg
  • 4,630
  • 2
  • 18
  • 27
  • edited my answer to use your original code with modifications. Presumably that is a start and you will do more. – RGuggisberg Mar 18 '16 at 03:27
  • I'm trying to use it in the for loop, but I have to be able to read the data and be able to modify it. There is another part of my code that I want to read in the exact same way basically but instead the lines look like: "Optimized Deck: 9 units: 86.6667: ......" that I want to get just a certain part of the data passed in, but when I try to I get nothing. – Thomas Morse Mar 18 '16 at 03:34
  • ok so the echo(!TEMP! displays what I want TEMP to actually contain, but when I try and change TEMP to be contain all but the first character, it is that C:\blah blah blah – Thomas Morse Mar 18 '16 at 03:46
  • Edited my answer so that the leading space is removed. – RGuggisberg Mar 18 '16 at 03:54
  • Ok the first issue will do for what I need, but the 2nd issue that I'm running into I need help with still. – Thomas Morse Mar 18 '16 at 04:10
  • I've only recently started to learn batch for the sake of automating some sims for a card game that I play, and I'm starting to think that I don't understand / can't find the documentation on /f how to use it properly. – Thomas Morse Mar 18 '16 at 04:26
  • It takes time and practice. Magoo took the time to highlight a number of very good points above. One thing you can do to GREATLY improve your chances for success is to write a few test programs to help you understand the difference between load/parse time behavior and run time behavior. A very large percentage of posts on this site deal with that and it is a concept that a lot of people have trouble with. – RGuggisberg Mar 18 '16 at 11:40