Get variables from unknown list of words

January 6, 2010 at 12:43:04
Specs: Windows XP
Thank you for this wonderful resource, normally I can find what I'm looking for through search and try but this one has me stumped.

I have a list of 6 words in a text file (one word per line) which are unknown prior to running batch (user input). So looks like this:

someword1
someword2
someword3
someword4
someword5
someword6

(nothing else in text file)

I need a batch to convert each word/line to a separate variable, something like this:

for /f "tokens=* delims= " %%a in (list.txt) do (
set /a N+=1
set v!N!=%%a
)
set unknown1=!v1!
set unknown2=!v2!
set unknown3=!v3!
set unknown4=!v4!
set unknown5=!v5!
set unknown6=!v6!

but how to type in the unknowns?


See More: Get variables from unknown list of words

Report •


#1
January 6, 2010 at 13:09:39
I think your FOR loop is good. But don't know what you're doing next.


=====================================
Helping others achieve escape felicity

M2


Report •

#2
January 6, 2010 at 13:35:39
Take first line (single word) from list.txt and set as variable1 in batch; set second line in list.txt as variable2 etc.

sorry if not clear, this would be easy if list to set as variables was known; unfortunately the list is generated via user input just prior to running the batch. The only known parameters are line numbers in text file (line1=var1, etc.) and that each line contains a single word with maximum of 6 lines (one word each) in text file.


Report •

#3
January 6, 2010 at 13:50:05
for /f "tokens=* delims= " %%a in (list.txt) do (
set /a N+=1
set variable!N!=%%a
)


=====================================
Helping others achieve escape felicity

M2


Report •

Related Solutions

#4
January 6, 2010 at 14:12:42
Sorry, I don't understand...

If I run your batch on list.txt containing:
--
Acronis
Photoshop
VirtualBox
--

I would expect to get output:

set Acronis=!v1!
set Photoshop=!v2!
set VirtualBox=!v3!

but remember these entries in list.txt are unknown and will change each time batch is run.

Truly sorry if I'm not being clear.


Report •

#5
January 6, 2010 at 14:22:59
Yeah, I'm not with you yet. I think the timing chain skipped a tooth.

Do you mean to do:

set Acronis=Acronis

If so, I fail to see the point.


=====================================
Helping others achieve escape felicity

M2


Report •

#6
January 6, 2010 at 14:58:14
one way you could do it maybe, do a "SET" without parameters to capture all the existing variables, then after your variable assignment, do SET again and any new items are your variable names. If you have a problem codeing it, just holler and i'll write one up.
my machine is acting real weird right now, it might be infected with a nasty! it's running real real slow!

Report •

#7
January 6, 2010 at 17:21:16
Had a little 'distraction' at work, I'm back...

M2, you're right of course but this is not a normal situation; I didn't want to put forward too much detail and confuse the question (too late). The batch I'm putting together (done except for this detail) is 'locked' (encoded) inside a script which runs as part of a much larger project (builds a PE boot disk that imports needed host drivers at each boot). The only user input allowed (prior to running the script builder) is a list of key words (like the example) used to strip out unwanted drivers from an, otherwise, auto-generated list. So, I was hoping to have the batch 'read' the text file (list of key words) to omit those drivers accordingly when the batch is run automatically during setup. Pertinent section of batch looks like this:
--
sdb_console /SAVE:NONMS /WIN:C:\WINDOWS /DEST:%drvdir%
del %drvdir%\*.log
dir %drvdir% > list.txt
setLocal EnableDelayedExpansion
for /f "tokens=* delims= " %%a in ('dir/b/a-d *.txt') do (
set N=
for /f "tokens=* delims= " %%e in (%%a) do (
set /a N+=1
if !N! gtr 5 echo %%e >> %%~Na.new
)
)
for /f "tokens=* delims= " %%a in (list.new) do (
set s=%%a
set s=!s:~39!
>> drvlist.txt echo.!s!
find /v "%V1%" < drvlist.txt > list.001
find /v "%V2%" < list.001 > list.002
find /v "%V3%" < list.002 > list.003
find /v "%V4%" < list.003 > list.004
find /v "%V5%" < list.004 > list.005
find /v "%V6%" < list.005 > last.txt
del li*
)
for /f "delims=" %%j in (last.txt) do echo.drvimpe -i:%drvdir%\%%j >> list.001
for /f "delims=" %%j in (list.001) do echo.%%j\ >> list.002
for /f "delims=" %%j in (list.002) do (
set line=%%j
set line=!line:C:\="C:\!
set line=!line: \=\"!
echo.!line!>> sysdipe.cmd
)
del l*
--

Now I'm thinking it would be better to append the batch directly (after extraction but before run), I think this is possible but need to test...

So what would be the easiest/best way to grab the list of drivers (list.txt in example) to echo/type into batch (in lieu of variables)? This keeps coming back to the same question in my mind, how to include data in a batch that is unknown when batch is written but where its exact location is known?


Report •

#8
January 6, 2010 at 17:33:05
I'm trying to get with you here and having no luck.

It may look different after some sleep.


=====================================
Helping others achieve escape felicity

M2


Report •

#9
January 6, 2010 at 17:49:24
No problem M2, have a good rest...

nbrane, just saw your post; sounds interesting but I would need to see an example. Hope your machine feels better soon ;~)


Report •

#10
January 6, 2010 at 21:50:34
thanks for the sympathy. i see a couple of weird "device drivers" running as TSRs and i'm kind of spooked till
i can get my kludge sterilized of them.

as for your conundrum:
this reminds me of another situation awhile back, where i did indeed set !xx!=!xx!, similar to what M2go commented:
set Acronis=Acronis

in that case, it was used to filter out any item that had already been entered, (by testing IF DEFINED !XX! then already entered, in other words, a unique value for each entry)
it seems like you could:
set xx=%%a (where %%a is incoming from the text file)
set !xx!=!xx! (this creates a variable whose name is the word from the text file and whose value is its own name, thus
making its name accessible to echo-output etc.)
echo !xx! is: !xx!
i agree it's kind of gnarley, but i know it can be done...
the more i look at your issue, the more confused i get!
(at least i'm in good company LoL!) it "looks" like you just want to remove (6 max) device-drivernames from a list, but I know i'm missing the point. (something to do with that part about "locked inside a script" and "encoded", i'm sure).
my initial post might still be an option but i don't think it needs to become that involved. k.i.s. & always shave with occams razor. Sorry i'm so muddled up.
ps: this is minor, but findstr can do all this in one go:

find /v "%V1%" < drvlist.txt > list.001
find /v "%V2%" < list.001 > list.002
find /v "%V3%" < list.002 > list.003
find /v "%V4%" < list.003 > list.004
find /v "%V5%" < list.004 > list.005
find /v "%V6%" < list.005 > last.txt

findstr /i /v "%v1 %v2% %v3%..."


Report •

#11
January 7, 2010 at 00:34:10
Thanks nbrane for the fine suggestions, I'm bleary eyed now but will take a closer look tomorrow...

I think I've worked it out, the real roadblock was peripheral; how to extract the batch to a temp folder upon user submittal of list, process and re-encode 'on-the-fly' - this is working now and therefore no need for variables. Sorry for confusion and wasted effort but a big thanks to you and M2 for helping me think it through. I got so caught up in this project I'm afraid the trees got in the way of the forest. Anyway, sorry about your machine; I hope you have a good partition backup image - saved me more times than I can count over the years.

Cheers ;~)


Report •

#12
January 8, 2010 at 16:58:32
@echo off
set dir=F:\Drivers
set v1=Acronis
set v2=Photosmart
set v3=VirtualBox
set v4=GeForce4
set v5=
set v6=
sdb_console /SAVE:NONMS /WIN:C:\WINDOWS /DEST:%dir%
del %dir%\*.log
dir %dir% > list.txt
setLocal EnableDelayedExpansion
for /f "tokens=* delims= " %%a in ('dir/b/a-d *.txt') do (
set N=
for /f "tokens=* delims= " %%e in (%%a) do (
set /a N+=1
if !N! gtr 5 echo %%e>> %%~Na.new
)
)
for /f "tokens=* delims= " %%a in (list.new) do (
set s=%%a
set s=!s:~39!
>> ldrv.txt echo.!s!
findstr /i /v "%v1% %v2% %v3% %v4% %v5% %v6%" < ldrv.txt > last.txt
)
set count=0
for /f "delims=" %%j in (last.txt) do (
set /A count+=1
echo.xcopy "%dir%\%%j" "%dir%\temp\!count!" /i /y>> lcpy.cmd
)
call lcpy.cmd
7za a -t7z %dir%\Test.7z -y %dir%\temp\* -r
rd /s /q %dir%\temp
del l*
--

Hey, I'm back :-)

Code above is working fine and does it's job as expected BUT (I can't believe I'm saying this) I have the same question I stated (perhaps poorly) in the first post! So I'm going to give it one last shot...

The batch section shown does the following:
>sets some internal variables.
>runs a console program (smart driver backup) that grabs system specific drivers from a host machine.
>generates a list of all the drivers collected.
>removes from the list all drivers whose name contains one of the key words provided by the user. (ex. 'Microsoft' would remove all drivers with the name Microsoft (good idea and actually done by default).
>Copies remaining drivers to a temp folder and zips them to a simple 'driver pack' for later processing by another program downstream.

OK, the section in bold is the problem, for obvious reasons, we don't want the user to edit the batch directly. When they type their key words in the (WinBuilder) interface, it ends up in a (text) file that will look like this (example only, names will change):
--
Acronis
Photosmart
VirtualBox
GeForce4
(empty)
(empty)
--
Max 6 lines, single word per line.

Question:

How do I echo the words from that list into the variable slots in the batch? i.e.

"Acronis" from text --> "set v1=Acronis" in batch etc. (v1-v6). That's the question, is it possible?


Report •

#13
January 8, 2010 at 19:31:27
hello again... now i'm getting kind of a different "take" on the issue, but still very confused. Now my concept is that you want one batchfile to write another batchfile, or else to modify itself, with "hardwired" variable assignments. I'm not sure what that would accomplish, since the same things happen.
at very top you have "set v1=acronis..." ie: hardwired var. assignment, not "set v1=%%a" or "set v1=%1", which leads me to the above conclusion. Normally, I would suggest that one batchfile "write" another batchfile (using the hardwired var assigmts) then call it, but i'm still not clear on what advantage this would have because you still have to read and incorporate the "userfiles":
ok, take your whole program above, except the hardwired lines:
set v1=Acronis
set v2=Photosmart
set v3=VirtualBox
set v4=GeForce4
set v5=
set v6=

take those out and save that as f/e "basecode.bat"
now, for each/any user modification of boot-load:

for /f "tokens=* delims=" %%b in (users.txt) do
set /a nn+=1
echo set v!nn!=%%b>>thisboot.bat
)
for /f "tokens=* delims=" %%a in (basecode.bat) do
echo %%a>>thisboot.bat
)
call thisboot.bat (?) (or is it called later down the pipe?)

now "thisboot.bat" will look almost identical to your script (i didn't bother with the prelims @echo off & set dir since they're not positionally critical) but my "burning question" is: what would this accomplish? (that "for %%a in user.txt do set v!nn!=%%a" would not?)
Your project has my interest, i am highly motivated to see what the outcome is (if i were a cat i would undoubtedly be dead, even with my nine allocated lives). I just feel like i'm really messed up somewhere and i want to figure out where my "timing chain jumped a tooth"! good luck and keep us posted...


Report •

#14
January 8, 2010 at 21:38:25
Hi nbrane, thanks for taking another stab at it! Maybe I'm not explaining this right but I'm trying my best, please bear with me...

Forget about the variables, they're not important (just easier for me). I just need to know how to get the words in the text file into the batch, that's it; I can figure out the rest. You've got a text file with a list of words on it, you don't know what those words are. How do you 'blindly' copy them into a batch?

Just that simple, possible or impossible, that's all there is to it. I realize I confused the question originally because, at that time, I didn't think the batch could be accessed (appended) directly due to it being encoded etc. Not important, I now have direct access to the batch file, I have direct access to the text file; how do I put them together?

Thanks for sticking with me ;-)


Report •

#15
January 9, 2010 at 09:58:48
maybe i'm oversimplifying this, but:
for /f "tokens=* delims=" %%b in (users.txt) do

reads the unknown words into %%b one at a time, and:
set /a nn+=1
set v!nn!=%%b

puts them into a set of variables sequentially named from
1 up, as v1, v2, v3... this gets them into the batch, making them accessible as variables with known/predictable names.
%v1% %v2% %v3%
but unknown/unpredictable values (usually) which are the usertextfile words / lines. the content of the variable is not critical, it is just a string to be removed from the list of drivers. the name of the variable plugs the value into the removal operation "findstr". this is my understanding at this point...
as far as i know, that's the only way to read a block of text into a batchscript, but i feel i'm still not "getting it". I guess if we were working in the same office, you could probably show me via the old fashioned methods like pencils and paper, and more sponaneous communications. and thank you for your patience!


Report •

#16
January 9, 2010 at 15:38:28
Thanks nbrane, that gives me an idea; let's see if I can work out the details (probably not today, no time to play...). Either way I'll let you know...

Report •

#17
January 10, 2010 at 13:15:21
Got it! Here's the bit that works for setting up the variables in the batch:

--
for /f "tokens=* delims= " %%a in (userin) do (
set /a N+=1
if !N! leq 6 echo %%a >> tmp
)
set count=0
for /f "delims=" %%j in (tmp) do (
set /A count+=1
echo.set v!count!=%%j>> sdbdipex.cmd
)
--
userin is the list of user input key words and the rest is echoed in before and after accordingly. Works great! Thanks guys, M2 for your input and especially nbrane for the very helpful support and suggestions. Your work is very important and we appreciate it more than you know!

Cheers ;~)


Report •

#18
January 10, 2010 at 14:01:52
Thanks, but it "weren't my idear", it was M2's way back up in post #3 ;)
it's a fairly common way of creating "arrays" in batch.
glad you got it working!

Report •

#19
January 10, 2010 at 15:22:36
Sorry, it took another 14 posts for it to sink through my thick skull. If not obvious, I'm still a newb and only starting to get it intuitively. So, no offense meant; thank you M2, you're brilliant!

Report •

#20
January 10, 2010 at 15:29:54
I'm glad you're getting some traction.

If it helps your planning, I've been at this this for over 20 years and it's apalling how much I don't know.

:(


=====================================
Helping others achieve escape felicity

M2


Report •

Ask Question