skip= in FOR /F fails

Oct 20, 2017
13
0
In the textfile "testskip.txt", I have to find the linenumber of the first line with "Platform ID:\t1", from that specific line the first linenumber with "Name ID:\t\t6" and from that specific line the first linenumber with "Offset:\t\t3". I wrote these lines of code:
Code:
@ECHO OFF

for /f %%i in ('ffind /F /L /K /M /E"Platform ID:\t1" TEST2.TXT') do @set PlatformID1LineNumber=%@STRIP[[],%%i]
echo (_1) PlatformID1LineNumber.: %PlatformID1LineNumber

for /f "skip=%%PlatformID1LineNumber%" %%i in ('ffind /F /L /K /M /E"Name ID:\t\t6" TEST2.TXT') do @set NameID6LineNumber=%@STRIP[[],%%i]
echo (_2) NameID6LineNumber.....: %NameID6LineNumber

for /f "skip=%%NameID6LineNumber%" %%i in ('ffind /F /L /K /M /E"Offset:\t\t3" TEST2.TXT') do @set OffsetLineNumber=%@STRIP[[],%%i]
echo (_3) OffsetLineNumber......: %OffsetLineNumber
The first FOR /F works great, but the second and third FOR /F not.
Even if I add the real linenumbers in "skip=", the code doesn't work.
I spend hours looking on the internet for solutions, I tried all kind of suggestions, but nothing works. I can't find the solution.
 

Attachments

May 20, 2008
9,286
62
Syracuse, NY, USA
I don't think it likes the "%%" in front of the variable name in the skip option. That variable should be expanded immediately.
Code:
v:\> type doggy.txt
My
dog
has
fleas.

v:\> set skipper=2

v:\> for /f "skip=%%skipper%" %%l in ('ffind /l /k /m /v /e".*" doggy.txt') do echo %l
[1]
[2]
[3]
[4]

v:\> for /f "skip=%skipper%" %%l in ('ffind /l /k /m /v /e".*" doggy.txt') do echo %l
[3]
[4]
 
Last edited:
May 20, 2008
9,286
62
Syracuse, NY, USA
This is a very different approach but it works well with your testskip.txt.
Code:
setlocal
do line in @testskip.txt

    if "%line" == "" iterate
    
    iff %@regex["Platform ID:\t1",%line] == 1 then
        set line1=%_do_loop
        unset /q line2
        unset /q line3
    elseiff %@regex["Name ID:\t\t6",%line] == 1 then
        set line2=%_do_loop
        unset /q line3
    else iff %@regex["Offset:\t\t3",%line] == 1 then
        set line3=%_do_loop
    endiff
    
    iff defined line1 .and. defined line2 .and. defined line3 then
        echo The lines are: %line1 %line2 %line3
        quit
    endiff
    
enddo

echo Not found!
Code:
v:\> testskip.btm
The lines are: 48 51 53
 
Oct 20, 2017
13
0
Hi Vince,

Thanks for helping my out, because I can't my head around it.

When I get "Platform ID:\t1" right (40), "Name ID:\t\t6" (51) and "Offset:\t\t3" (53) will not work.
When I get "Platform ID:\t1" wrong (48), "Name ID:\t\t6" (51) and "Offset:\t\t3" (53) will work.
Like your code.

The right answer is: 40, 51, 53, not: 48, 51, 53.

Cracking my head continues ...

Marcel - Win7Ulti/x64/SP1
 
Oct 20, 2017
13
0
Hi Vince,

If you remove from the line: ffind /l /k /m /v /e".*" option "/v" (showing every marching line on a text search), the result is not 48 but 40.

But now the 2nd and 3rd line. Keep on cracking my head.

Marcel - Win7Ulti/x64/SP1
 
May 20, 2008
9,286
62
Syracuse, NY, USA
Hi Vince,

Thanks for helping my out, because I can't my head around it.

When I get "Platform ID:\t1" right (40), "Name ID:\t\t6" (51) and "Offset:\t\t3" (53) will not work.
When I get "Platform ID:\t1" wrong (48), "Name ID:\t\t6" (51) and "Offset:\t\t3" (53) will work.
Like your code.

The right answer is: 40, 51, 53, not: 48, 51, 53.

Cracking my head continues ...

Marcel - Win7Ulti/x64/SP1
Why do you want 40 instead of 48? I figured you wanted all three line numbers to come from the same "section", namely this one, the last one:
Code:
      0. Platform ID:    1
         Specific ID:    0
         Language ID:    0
         Name ID:        6
         Length:        0
         Offset:        3
 
Oct 20, 2017
13
0
Hi Vince,

The textfile is a sample of the output of TTFDUMP.EXE, which dumps TrueTypeFont information in a textfile.
The structure is explained in Font Names Table.

My goal is to find the "section" with the 3 lines, but I don't know how I can find this section in one search.
So, first I have to find the first section with "Platform ID: 1", several section later I find the section with "Platform ID: 1" and "Name ID: 6" and so on.

Your very different approach was my first working code, but very slow. The dumps can be very long > 400 lines, with takes time to search. My second approach is to feed FFIND lines to search by the FOR /F loop and to use the skip= option so earlier sections are not searched anymore. Otherwise searching for "Name ID: 6" finds a section that starts with "Platform ID: 0".

I suspect that the options of FFIND have influence. I'll look at FIND.EXE and FINDSTR.exe and keep on cracking this problem.

Marcel - Win7Ulti/x64/SP1
 
May 20, 2008
9,286
62
Syracuse, NY, USA
So 48 51 53 is what you want, right? My approach finds it in one pass through the file. I think that will be very hard to do with FOR and FFIND (or FIND.EXE or FINDSTR.EXE) unless you LEAVEFOR when appropriate and wrap the "FOR ... FOR ... FOR" approach in another loop. If you can get that to work, I suspect it'll be quite slow.

Do you have a Gnu GREP.EXE? With it I can do this quite quickly.

Code:
v:\> g:\gnu\grep.exe -n -P  "Platform.*1\n.*\n.*\n.*Name.*6\n.*\n.*Offset.*3" testskip.txt
48:       0. Platform ID:       1
             Specific ID:       0
             Language ID:       0
             Name ID:           6
             Length:            0
             Offset:            3
 
May 20, 2008
9,286
62
Syracuse, NY, USA
And with FFIND:

Code:
v:\> ffind /k /m /l /v /e"Platform.*1\r\n.*\r\n.*\r\n.*Name.*6\r\n.*\r\n.*Offset.*3" testskip.txt
[48]      0. Platform ID:       1
Or, if you want to get really fancy:

Code:
v:\> echo %@strip[[],%@word[0,%@execstr[ffind /k /m /l /v /e"Platform.*1\r\n.*\r\n.*\r\n.*Name.*6\r\n.*\r\n.*Offset.*3" testskip.txt]]]
48
 
Oct 20, 2017
13
0
Hi Vince,

Your last line of code works perfect :smile:

It accelerates the execution of the batch file 22 times!

Thanks again,

Marcel - Win7Ulti/x64/SP1