[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now


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

Posted on 2003-10-21
Medium Priority
Last Modified: 2012-06-21
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
Question by:akourafas
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
LVL 16

Expert Comment

ID: 9593826
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


Author Comment

ID: 9594088
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

Author Comment

ID: 9594103
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

Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

LVL 16

Expert Comment

ID: 9594112
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

LVL 16

Accepted Solution

_nn_ earned 800 total points
ID: 9594174
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%

Assisted Solution

K_2K earned 200 total points
ID: 9600025
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

NFR key for Veeam Agent for Linux

Veeam is happy to provide a free NFR license for one year.  It allows for the non‑production use and valid for five workstations and two servers. Veeam Agent for Linux is a simple backup tool for your Linux installations, both on‑premises and in the public cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Using dates in 'DOS' batch files has always been tricky as it has no built in ways of extracting date information.  There are many tricks using string manipulation to pull out parts of the %date% variable or output of the date /t command but these r…
VALIDATING DATES One method of validating dates is to jam the date into the DATE command and see if it accepts it by examining the system's errorlevel value. A non-zero result indicates failure. A typical example might look something like the fol…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Suggested Courses

650 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question