Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

skip= in FOR /F fails

Oct
31
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

  • testskip.btm
    569 bytes · Views: 272
  • testskip.txt
    877 bytes · Views: 304
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:
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 

Similar threads

Back
Top