• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1090
  • Last Modified:

How do I use the FOR /f statement to remove unwanted characters and set an enviroment variable

for /f "eol=; tokens=6 delims=\ " %%i in ("%TEMP%") do set TSSID=%%i
(This works properly & TSSID= the users terminal ID fine)

'REGfree.EXE -listvalue "HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\Device
(this generates the value "HP Laserjet 4000 Series/BOB/Session 3,winspool,TS007)

for /f "Tokens=2 Delims=, " %%i in ('REGfree.EXE -listvalue "HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\Device"') do set prt=%%i
(this generatesthe value "HP 3")  Thats not what I was trying to do :-)

I would like to retrive the "HP Laserjet 4000 Series/BOB/Session 3" portion of the query
  • 3
  • 2
2 Solutions
I'm not sure where the "HP 3" comes from, but could you test removing the space you have in the delims clause ?

for /f "tokens=2 delims=," %%i in ('REGfree.EXE -listvalue "HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\Device"') do set prt=%%i

akourafasAuthor Commented:
When i run this:
'REGfree.EXE -listvalue "HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\Device

I get:
REG_SZ HP Laserjet 4000 Series/RKM/Session 3,winspool,TS007
when trying to get:
HP Laserjet 4000 Series/RKM/Session 3

this part: "For /f "Tokens=2........."
extracted th HP

The number 3 was the script value extracted using:
for /f "eol=; tokens=6 delims=\ " %%i in ("%TEMP%") do set TSSID=%%i

Thanks for the quick response
akourafasAuthor Commented:
Heres the script:

net use lpt1: /delete /y

for /f "eol=; tokens=6 delims=\ " %%i in ("%TEMP%") do set TSSID=%%i

for /f "Tokens=2 Delims=, " %%i in ('REGfree.EXE -listvalue "HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\Device"') do set prt=%%i

set TSPrinterName=%prt% %TSSID%
rundll32 printui.dll,PrintUIEntry /Xs /n "%TSPrinterName%" sharename "TSPrinter%TSSID%" attributes +Shared

net use lpt1: \\\TSPrinter%TSSID% /y

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

aah, ok. In which case, I'd do it like this :

for /f "tokens=2* eol=," %%i in ('REGfree.EXE -listvalue "HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\Device"') do set prt=%%i

grmbl, the syntax looks correct, but it doesn't want to work here, sorry.

Alternative :

for /f "delims=," %%i in ('REGfree.EXE -listvalue "HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\Device"') do set prt=%%i

set TSPrinterName=%prt:~7,-1% %TSSID%
Nice job, That should work fine, likely stripping the 3 off the end.  
%prt:~7,-1%   says "skip 7 letters and use all but the last one"  
%prt:~7%       says "skip 7 letters and use the rest"  
Unfortunately, my preferred "skip 7 letters and use all but the last zero" (:~7,-0) returns a null or empty string so I can't explicitly state the -0 at the end.

I only dropped this "why" post to help with future for loops, not trying to make any of it look "acceptable" for the question _nn_ has already answered.

I think the key to solving these in future for loops is to study the ["options"] and examples in "for /?" as well as studying output lines for all possible values of a command you wish to split.
I knew UNIX FOREACH and AWK before, and when I first looked at MS-DOS's FOR all I could say was "What were they (MS) thinking?"  Reading the 3 or 4 paragraphs after each example in the help while looking back at the example to see what option accomplishes each explaination is a good way to begin understanding what they were thinking.  Luckily we don't have to agree or defend what they setup, we only wish to learn to use it.

Delims=  is one commonly misunderstood option.  MS's help line: "This replaces the default delimiter set of space and tab." is so guardedly correct it becomes unclear.  If the option is left out any number or combination of spaces or tabs will separate fields.
If included, nothing but what you put after = separates fields.  However, it's not always easy to know if FOR will think you meant to include a space unless you always place delims= as the last option.  (Notice it's not what I think that matters, it's what FOR thinks.)  That way everything between the = and the " including a space or another = or an escaped special character becomes a field separator.   Field separators do not get included in fields. ( exception: If an * is included in tokens= then the last variable set by FOR may include separators, but let's not go there at this time.  Leaving * out of all options is best if possible)
  "tokens=2 delims=, " 
Will break the line at all spaces and commas.  Hence the value you have with spaces in it is broken to several fields.  Since the printer name could be changed by any one person for their own taste it's not possible to know how many fields, in reality.
  "tokens=2 delims=,="
Will break the line at all commas and equal signs and spaces no longer matter.  (sidenote: "tokens=2 delims==," means the same thing, but other places in DOS give == special meaning, so I try to write it as above to avoid confusion.  The DOS example that uses ONLY = as a delimeter was needed but not well explained.  It was NOT a special meaning of == but a normal delimeter.)

Once the delimeters and fields can easily be counted, tokens become easier to choose and variables become predictable.  Tokens= is mostly well understood except that the default is first field ONLY and blank fields don't count.  Some say that can't be since I have many code clippets that take the whole line with the tokens option omitted.  Such codes include "delims=" which replace default delimiters with no delimiters.  That forces the line to be all one field.  The default token of first field only now works.  Some code does not include "delims=" and seems to be the entire line because all lines tested have no tabs or spaces.  In reality it is only using the first field and someday that code may lose parts of some lines if the data changes.

From _nn_'s fix, I'm guessing the line from his REGfree.EXE is much more friendly than MS's REG.EXE gives, looking something like this:
     Device=HP Laserjet 4000 Series/BOB/Session 3,winspool,TS007
If we know by REGfree there will always be an = between valuename and data (i don't know REGfree) then = would seem to be a good separator.
I do know the windows printer setup routines refuse to save a printer name that includes a comma so that also makes a good separator. (You already knew that)  I just changed my generic printer (Windows 2000) to "Generic / Text Only = to file" to see if I could force "tokens=2 delims=,=" to break and it worked (didn't work?).  
We could separate with = only and abuse the * special case to get all but the first = into the second field using "tokens=1* delims==" %%i  but then %%j becomes the part we need to keep, AND we must still break the fields by commas separately with another added for:  for /f "delims=," %%K in ("%%j") do set prt=%%K

Anyway, _nn_'s simple solution of using comma ONLY as a separator forcing first token to always become the same 7 letter skippable string (we know the valuename is always the same in this case) plus the correct value is faster and more elegant.  As I said, I only dropped this "why" post to ...


Featured Post

[Webinar] Improve your customer journey

A positive customer journey is important in attracting and retaining business. To improve this experience, you can use Google Maps APIs to increase checkout conversions, boost user engagement, and optimize order fulfillment. Learn how in this webinar presented by Dito.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now