Computing.Net > Forums > Programming > Batch for loop tokens

Computing.Net: Over 1,000,000 posts about all things technology related! Over 90% answered within 24 hours! Click here to sign up now, it's free!

Batch for loop tokens

Reply to Message Icon

Original Message
Name: Daniel Mott
Date: July 23, 2008 at 15:44:16 Pacific
Subject: Batch for loop tokens
OS: XP SP2
CPU/Ram: 2048
Model/Manufacturer: HP
Comment:

I am trying to do something for each token in a line of a text file but I have an unknown number of tokens. The tokens are separated by "/". How do I process all valid tokens?

for /F "tokens=<what goes here?> delims=/" %%A in (List.txt) do (
<do something for each valid token>
)

Thanks.


Report Offensive Message For Removal


Response Number 1
Name: Mechanix2Go
Date: July 23, 2008 at 15:58:27 Pacific
Reply: (edit)

:: process each token

@echo off
setLocal EnableDelayedExpansion

for /f "tokens=* delims=/" %%a in (myfile) do (
call :sub1 %%a
)
goto :eof

:sub1

:loop
echo do %1
shift
if not %1'==' goto loop
goto :eof


=====================================
If at first you don't succeed, you're about average.

M2


Report Offensive Follow Up For Removal

Response Number 2
Name: klint
Date: July 23, 2008 at 16:14:02 Pacific
Reply: (edit)

set line=one/two/three
:processToken
for /f "tokens=1* delims=/" %%a in ("%line%") do (
echo Got one token: %%a
set line=%%b
)
if not "%line%" == "" goto :processToken


Report Offensive Follow Up For Removal

Response Number 3
Name: Daniel Mott
Date: July 24, 2008 at 07:39:29 Pacific
Reply: (edit)

To Mechanix2Go, when calling a 'function' ..i.e. call :sub1 %%a the function uses the space as a delim instead of keeping the same delim as the for loop. How do I make it treat the parameters (%1,%2,...%9) with delim "/" ?


Report Offensive Follow Up For Removal

Response Number 4
Name: Mechanix2Go
Date: July 24, 2008 at 07:54:06 Pacific
Reply: (edit)

Hi Daniel,

You're absolutely right. Why it behaves that way is beyond me. Maybe somebody can enlighten us.

Try this:

::============================
@echo off
setLocal EnableDelayedExpansion

for /f "tokens=* delims= " %%a in (myfile) do (
set str=%%a
set str=!str:/= !
call :sub1 !str!
)
goto :eof

:sub1

:loop
echo do %1
shift
if not %1'==' goto loop
goto :eof


=====================================
If at first you don't succeed, you're about average.

M2


Report Offensive Follow Up For Removal

Response Number 5
Name: Daniel Mott
Date: July 24, 2008 at 07:54:06 Pacific
Reply: (edit)

So basically my current solution combines both of your responses..

@echo off
setLocal EnableDelayedExpansion

for /f "tokens=* delims=/" %%a in (List.txt) do (
set line=%%a
call :sub1 line
)
goto :eof

:sub1

:processToken
for /f "tokens=1* delims=/" %%a in ("%line%") do (
echo Got one token: %%a
set line=%%b
)
if not "%line%" == "" goto :processToken
goto :eof

First part to grab the line, 2nd part to process the line.. is this the most efficient way? I am operating on a large text file so efficiency is somewhat important. Thanks for both your help.


Report Offensive Follow Up For Removal


Response Number 6
Name: Daniel Mott
Date: July 24, 2008 at 07:59:31 Pacific
Reply: (edit)

I see what you are trying to do with replacing the / with the space except that my tokens are allowed to have spaces and thus what should be one token is split into multiple tokens. Do you see my previous post as a decent solution?


Report Offensive Follow Up For Removal

Response Number 7
Name: Mechanix2Go
Date: July 24, 2008 at 08:13:51 Pacific
Reply: (edit)

Yeah, I think it will work but this behavior of / as delim is very troubling. I'm wondering what else is lurking in the weeds, waiting to not work at a really inconvenient time.


=====================================
If at first you don't succeed, you're about average.

M2


Report Offensive Follow Up For Removal

Response Number 8
Name: klint
Date: July 24, 2008 at 08:58:07 Pacific
Reply: (edit)

If, as you say, you've got a large file and efficiency is important, consider using a text processing utility such as awk, which can process the file much faster than a batch file.


Report Offensive Follow Up For Removal

Response Number 9
Name: Mechanix2Go
Date: July 24, 2008 at 09:00:18 Pacific
Reply: (edit)

Hi klint,

Any idea why / does not work as delim?


=====================================
If at first you don't succeed, you're about average.

M2


Report Offensive Follow Up For Removal

Response Number 10
Name: klint
Date: July 24, 2008 at 09:38:30 Pacific
Reply: (edit)

M2, I think it's just that a subroutine's arguments are processed the same way as a batch file's command-line arguments: the delimiters are space, tab and semicolon. When you specify for /l "delims=/", that only affects the loop variables (so that %%a is the first token delimited by /, %%b the next, etc.)


Report Offensive Follow Up For Removal

Response Number 11
Name: Mechanix2Go
Date: July 24, 2008 at 10:25:15 Pacific
Reply: (edit)

Notice that in the first section, it spits out the tokens as expected.

2nd section it echos the /, wich is the delim.

What's going on?

::==================
@echo off > newfile
setLocal EnableDelayedExpansion

for /f "tokens=1-5 delims=/" %%a in (myfile) do (
echo %%a
echo %%b
echo %%c
)

for /f "tokens=* delims=/" %%a in (myfile) do (
echo %%a
)


=====================================
If at first you don't succeed, you're about average.

M2


Report Offensive Follow Up For Removal

Response Number 12
Name: klint
Date: July 24, 2008 at 10:51:08 Pacific
Reply: (edit)

It's because of the tokens=*. Here's a snippet from the for/? help text:

----
tokens=x,y,m-n - specifies which tokens from each line are to
be passed to the for body for each iteration.
This will cause additional variable names to
be allocated. The m-n form is a range,
specifying the mth through the nth tokens. If
the last character in the tokens= string is an
asterisk, then an additional variable is
allocated and receives the remaining text on
the line after the last token parsed.

----

So when you write tokens=* there is only one variable and it "receives the remaining text on the line" which is, in this case, the whole line.


Report Offensive Follow Up For Removal

Response Number 13
Name: Mechanix2Go
Date: July 24, 2008 at 11:00:34 Pacific
Reply: (edit)

Hi klint,

I guess you're right but it seems pretty lame to include delims.

I'm going to look at your first solution and see if I can get my head round it.


=====================================
If at first you don't succeed, you're about average.

M2


Report Offensive Follow Up For Removal

Response Number 14
Name: Mechanix2Go
Date: July 24, 2008 at 11:15:51 Pacific
Reply: (edit)

@echo off

for /f "tokens=* delims= " %%f in (myfile) do (
set line=%%f
call :processToken
)
goto :eof

:processToken

for /f "tokens=1* delims=/" %%a in ("%line%") do (
echo Got one token: %%a
set line=%%b
)
if not "%line%" == "" goto :processToken
goto :eof

::==============================================
Thanks to klint for bailing us out on this one.


=====================================
If at first you don't succeed, you're about average.

M2


Report Offensive Follow Up For Removal






Post Locked

This post is quite old and has been locked from receiving new replies. Please create a new posting instead.


Go to Programming Forum Home








Do you own an iPhone?

Yes
No, but soon
No


View Results

Poll Finishes In 7 Days.
Discuss in The Lounge
Poll History




Data Recovery Software