Discussion:
Counting tokens in a for loop
(too old to reply)
Arno
2006-01-10 09:25:44 UTC
Permalink
Hi all,

I try to parse lines in a file with "for /f ...". Is there a simple way
to find out how many tokens are in every line? Has "for" something like
'argc'?

Regards
Arno
foxidrive
2006-01-10 09:38:58 UTC
Permalink
Post by Arno
I try to parse lines in a file with "for /f ...". Is there a simple way
to find out how many tokens are in every line? Has "for" something like
'argc'?
No, and the solution depends on the makeup of the file - commas,
semicolons, equals, spaces etc and if there are any 'poison' characters for
batch files.
Arno
2006-01-11 08:18:22 UTC
Permalink
How can a solution look like for a semicolon separated list? Are ther
some examples available?

regards
Arno
foxidrive
2006-01-11 10:46:24 UTC
Permalink
Post by Arno
How can a solution look like for a semicolon separated list? Are ther
some examples available?
Expects semicolon separated list of alphanumeric text items.

@echo off
for /f "delims=" %%a in (file.txt) do call :next %%a
goto :EOF
:next
set num=0
:loop
if not [%1]==[] set /a num=num+1&shift&goto :loop
echo %num% items were found
Arno
2006-01-11 12:41:20 UTC
Permalink
Great, thanks a lot, this solution is much easier, than this what I
have tried, and it works for blanks too. The only thing, what I want to
ask addtional is, it seeems so, that I can't count the lines in the
same step, because 'for' skip empty lines. So, do I have to do the line
count separat, or is it also possible in one step?

regards
Arno
billious
2006-01-11 13:49:39 UTC
Permalink
Post by Arno
Great, thanks a lot, this solution is much easier, than this what I
have tried, and it works for blanks too. The only thing, what I want to
ask addtional is, it seeems so, that I can't count the lines in the
same step, because 'for' skip empty lines. So, do I have to do the line
count separat, or is it also possible in one step?
regards
Arno
It would help if you were to say what you want to do rather than leaving us
to guess.

Batch processing is unlike conventional programming. The facilities
available are OS-dependent and the methodology often depends the content of
the data to be processed.

If you want to process blank lines with a FOR /F for instance, for NT/2K/XP
(for which a better group is arguably alt.msdos.batch.nt) then because, as
you have observed, FOR /F skips blank lines, then you have to press other
techniques into play.

for /f "tokens=1*delims=[]" %%i in ('find /n /v "" filename.txt') do call
:next %%j

for instance will call the parameter-counting routine with EACH line of
filename.txt, empty or not (incidentally, if you pass %%i to :next, %%i will
contain the line-number)

This technique is not required if you don't have blank lines, and the
processing performed by the :next routine may have problems with some
characters that may be contained in filename.txt.

It's a lot easier to use
for /f "delims=" %%a in (file.txt) do call :next %%a
than
for /f "tokens=1*delims=[]" %%i in ('find /n /v "" filename.txt') do call
:next %%j

but the latter is a sledgehammer to crack a nut in the simple case - and
would then be almost inevitably be followed by a question "how do I ignore
blank lines?"

If you were to reveal what you're trying to do, your OS and relevant data
contents, then we're more able to help. Otherwise, it becomes a game of
twenty questions.

HTH

...Bill
Arno
2006-01-11 15:08:48 UTC
Permalink
Thanks Bill,

it works fine for me. At least it should run on NT/2000/XP/2003 and
what I want to do is counting tokens per line and all lines in a normal
ascii file.
The only thing, what happen on my side, is that if the file has empty
lines at the end the batch misses the last two lines. So, if I see in
my editor, that a file has 12 lines and the last four lines are empty
my batch count only 10 lines. It seems to be a problem in 'find' what
is running on XP SP2. Can you explain this behaviour? Is it a bug of
'find'?

...Arno

Here is the actual state of the testbatch:
@echo off
setlocal
set /a lines=0
for /f "tokens=1* delims=[]" %%a in ('find /n /v "" SomeText.txt') do
call :next %%b

echo The File has %lines% line(s)
endlocal
goto :EOF

:next
:: skip the first line, because it is the filename
if not defined first set first=1&goto :EOF
set /a lines+=1
set num=0
:loop
if not [%1]==[] set /a num+=1&shift&goto :loop
echo %num% items were found!
goto :EOF
foxidrive
2006-01-11 15:33:22 UTC
Permalink
Post by Arno
Thanks Bill,
it works fine for me. At least it should run on NT/2000/XP/2003 and
what I want to do is counting tokens per line and all lines in a normal
ascii file.
The only thing, what happen on my side, is that if the file has empty
lines at the end the batch misses the last two lines. So, if I see in
my editor, that a file has 12 lines and the last four lines are empty
my batch count only 10 lines. It seems to be a problem in 'find' what
is running on XP SP2. Can you explain this behaviour? Is it a bug of
'find'?
There is a bug in find which skips the last line if it is empty.

Test it with this command line:
for /f %a in ('find /c /v "" ^< file.txt') do echo %a

You could get around it by echoing a character into the end of the file,
counting the lines and subtracting one.
(untested:)

copy "datafile.txt" file.txt
echo.a>>file.txt
for /f %%a in ('find /c /v "" ^< file.txt') do set /a num=%%a-1
del file.txt
Post by Arno
...Arno
@echo off
setlocal
set /a lines=0
for /f "tokens=1* delims=[]" %%a in ('find /n /v "" SomeText.txt') do
call :next %%b
echo The File has %lines% line(s)
endlocal
goto :EOF
:next
:: skip the first line, because it is the filename
if not defined first set first=1&goto :EOF
set /a lines+=1
set num=0
:loop
if not [%1]==[] set /a num+=1&shift&goto :loop
echo %num% items were found!
goto :EOF
Arno
2006-01-11 16:13:13 UTC
Permalink
This work fine.
Many thanks for your time
...Arno

Continue reading on narkive:
Loading...