Shorten a function [SOLVED]

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Shorten a function [SOLVED]

#1 Post by abc0502 » 30 Jul 2012 02:06

Hi, I made a function that fix page numbers in a file but it is limited to a specified line numbers, so if the file that it is working on exceeds 9 lines it won't modify it, i tried to change it and make it more global so it process any numbers of lines but i couldn't.

This is how the function work:

Code: Select all

Call :Fix_page_numbers "D:\Input_File.txt" "D:\Output_File.txt"  

And this is the function:

Code: Select all

:Fix_page_numbers
SETLOCAL EnabLeDeLayedExpansion
for /f "tokens=* deLims=" %%a in (%~1) do (
set /a N+=1
set L!N!=%%a
)
:: setting possibLe Lines max possibLe Line is 9
set Line1=!L1!
set Line2=!L2!
set Line3=!L3!
set Line4=!L4!
set Line5=!L5!
set Line6=!L6!
set Line7=!L7!
set Line8=!L8!
set Line9=!L9!

For /f "tokens=1,2,* delims=/," %%a in ("%line1%") do (
      set constant=%%b
      set previous1=1
      echo.WORLD/!previous1!,%%c>>%~2
)

:: Here we continue to check line 2
For /f "delims=" %%a in ("%line2%") do (
   echo "%%a" |find "   " >nul
   if !errorlevel! EQU 1 ( goto parent2   
   ) else ( goto child1 )
   )

:parent2
   For /f "tokens=1,2,* delims=/," %%a in ("%line2%") do (
         set current2=%%b
         set /a previous2 = previous1 + 1
         echo.KPI/!previous2!,%%c>>%~2
   )
   goto line3
            
:child1
   For /f "tokens=1,2,* delims=/," %%a in ("%line2%") do (
         set current2=%%b
         set /a check = current2 - current1
         if !check! EQU 0 (
            set previous2=!previous1!
            echo.%%a/!previous2!,%%c>>%~2
         ) Else (
            set /a previous2 = check + previous1
            echo.KPI/!previous2!,%%c>>%~2 )
   )
   goto line3
   
:line3
:: Here we continue to check line 3
For /f "delims=" %%a in ("%line3%") do (
   echo "%%a" |find "   " >nul
   if !errorlevel! EQU 1 ( goto parent3   
   ) else ( goto child2 )
   )

:parent3
   For /f "tokens=1,2,* delims=/," %%a in ("%line3%") do (
         set current3=%%b
         set /a previous3 = previous2 + 1
         echo.WORK/!previous3!,%%c>>%~2
   )
   goto line4
            
:child2
   For /f "tokens=1,2,* delims=/," %%a in ("%line3%") do (
         set current3=%%b
         set /a check = current3 - current2
         if !check! EQU 0 (
            set previous3=!previous2!
            echo.%%a/!previous3!,%%c>>%~2
         ) Else (
            set /a previous3 = check + previous2
            echo.%%a/!previous3!,%%c>>%~2 )
   )
   goto line4   

:line4
:: Here we continue to check line 4
For /f "delims=" %%a in ("%line4%") do (
   echo "%%a" |find "   " >nul
   if !errorlevel! EQU 1 ( goto parent4   
   ) else ( goto child3 )
   )

:parent4
   For /f "tokens=1,2,* delims=/," %%a in ("%line4%") do (
         set current4=%%b
         set /a previous4 = previous3 + 1
         echo.WORK/!previous4!,%%c>>%~2
   )
   goto line5
   
:child3
   For /f "tokens=1,2,* delims=/," %%a in ("%line4%") do (
         set current4=%%b
         set /a check = current4 - current3
         if !check! EQU 0 (
            set previous4=!previous3!
            echo.%%a/!previous4!,%%c>>%~2
         ) Else (
            set /a previous4 = check + previous3
            echo.%%a/!previous4!,%%c>>%~2 )
   )
   goto line5

:line5
:: Here we continue to check line 5
For /f "delims=" %%a in ("%line5%") do (
   echo "%%a" |find "   " >nul
   if !errorlevel! EQU 1 ( goto parent5   
   ) else ( goto child4 )
   )

:parent5
   For /f "tokens=1,2,* delims=/," %%a in ("%line5%") do (
         set current5=%%b
         set /a previous5 = previous4 + 1
         echo.WORK/!previous5!,%%c>>%~2
   )
   goto line6

:child4
   For /f "tokens=1,2,* delims=/," %%a in ("%line5%") do (
         set current5=%%b
         set /a check = current5 - current4
         if !check! EQU 0 (
            set previous5=!previous4!
            echo.%%a/!previous5!,%%c>>%~2
         ) Else (
            set /a previous5 = check + previous4
            echo.%%a/!previous5!,%%c>>%~2 )
   )
   goto line6

:line6
:: Here we continue to check line 6
For /f "delims=" %%a in ("%line6%") do (
   echo "%%a" |find "   " >nul
   if !errorlevel! EQU 1 ( goto parent6   
   ) else ( goto child5 )
   )

:parent6
   For /f "tokens=1,2,* delims=/," %%a in ("%line6%") do (
         set current6=%%b
         set /a previous6 = previous5 + 1
         echo.WORK/!previous6!,%%c>>%~2
   )
   goto line7

:child5
   For /f "tokens=1,2,* delims=/," %%a in ("%line6%") do (
         set current6=%%b
         set /a check = current6 - current5
         if !check! EQU 0 (
            set previous6=!previous5!
            echo.%%a/!previous6!,%%c>>%~2
         ) Else (
            set /a previous6 = check + previous5
            echo.%%a/!previous6!,%%c>>%~2 )
   )
   goto line7
   
:line7
:: Here we continue to check line 7
For /f "delims=" %%a in ("%line7%") do (
   echo "%%a" |find "   " >nul
   if !errorlevel! EQU 1 ( goto parent7   
   ) else ( goto child6 )
   )

:parent7
   For /f "tokens=1,2,* delims=/," %%a in ("%line7%") do (
         set current7=%%b
         set /a previous7 = previous6 + 1
         echo.WORK/!previous7!,%%c>>%~2
   )
   goto line8

:child6
   For /f "tokens=1,2,* delims=/," %%a in ("%line7%") do (
         set current7=%%b
         set /a check = current7 - current6
         if !check! EQU 0 (
            set previous7=!previous6!
            echo.%%a/!previous7!,%%c>>%~2
         ) Else (
            set /a previous7 = check + previous6
            echo.%%a/!previous7!,%%c>>%~2 )
   )
   goto line8
   
:line8
:: Here we continue to check line 8
For /f "delims=" %%a in ("%line8%") do (
   echo "%%a" |find "   " >nul
   if !errorlevel! EQU 1 ( goto parent8   
   ) else ( goto child7 )
   )

:parent8
   For /f "tokens=1,2,* delims=/," %%a in ("%line8%") do (
         set current8=%%b
         set /a previous8 = previous7 + 1
         echo.WORK/!previous8!,%%c>>%~2
   )
   goto line9

:child7
   For /f "tokens=1,2,* delims=/," %%a in ("%line8%") do (
         set current8=%%b
         set /a check = current8 - current7
         if !check! EQU 0 (
            set previous8=!previous7!
            echo.%%a/!previous8!,%%c>>%~2
         ) Else (
            set /a previous8 = check + previous7
            echo.%%a/!previous8!,%%c>>%~2 )
   )
   goto line9
   
:line9
:: Here we continue to check line 8
For /f "delims=" %%a in ("%line9%") do (
   echo "%%a" |find "   " >nul
   if !errorlevel! EQU 1 ( goto parent9   
   ) else ( goto child8 )
   )

:parent9
   For /f "tokens=1,2,* delims=/," %%a in ("%line9%") do (
         set current9=%%b
         set /a previous9 = previous8 + 1
         echo.WORK/!previous9!,%%c>>%~2
   )
   goto :eof

:child8
   For /f "tokens=1,2,* delims=/," %%a in ("%line9%") do (
         set current9=%%b
         set /a check = current9 - current8
         if !check! EQU 0 (
            set previous9=!previous8!
            echo.%%a/!previous9!,%%c>>%~2
         ) Else (
            set /a previous9 = check + previous8
            echo.%%a/!previous9!,%%c>>%~2 )
   )
Endlocal
goto :eof

This function should modify a file like this:
The page nubrs are between the / and ,

Code: Select all

NL/3,Black,notBold,notItalic,open,TopLeftZoom,1,0,0.0
NL/3,Black,notBold,notItalic,closed,TopLeftZoom,1,0,0.0
   KPI1/3,Black,notBold,notItalic,open,TopLeftZoom,213,8,0.0
   KPI2/3,Black,notBold,notItalic,open,TopLeftZoom,469,8,0.0
   KPI3/4,Black,notBold,notItalic,open,TopLeftZoom,63,8,0.0
NL/3,Black,notBold,notItalic,closed,TopLeftZoom,1,0,0.0
   WORK1/3,Black,notBold,notItalic,open,TopLeftZoom,213,8,0.0
   WORK2/3,Black,notBold,notItalic,open,TopLeftZoom,469,8,0.0
   WORK3/4,Black,notBold,notItalic,open,TopLeftZoom,63,8,0.0

so it looks like this:

Code: Select all

NL/1,Black,notBold,notItalic,open,TopLeftZoom,1,0,0.0
NL/2,Black,notBold,notItalic,closed,TopLeftZoom,1,0,0.0
   KPI1/2,Black,notBold,notItalic,open,TopLeftZoom,213,8,0.0
   KPI2/2,Black,notBold,notItalic,open,TopLeftZoom,469,8,0.0
   KPI3/3,Black,notBold,notItalic,open,TopLeftZoom,63,8,0.0
NL/4,Black,notBold,notItalic,closed,TopLeftZoom,1,0,0.0
   WORK1/4,Black,notBold,notItalic,open,TopLeftZoom,213,8,0.0
   WORK2/4,Black,notBold,notItalic,open,TopLeftZoom,469,8,0.0
   WORK3/5,Black,notBold,notItalic,open,TopLeftZoom,63,8,0.0


The first line should always has a page number 1 and the second line should always has a page number 2,
but when it come to 3rd line to the 9th, it checks to see if the previous line has the same number "original number"
if it has then the new page number should have the same new page number as the previous but if it hasn't it calculate the difference and add that to the previous new number and set it as the new page number to that line, and so is the rest of the file

starting from line 3 and to the end it should be a repeated function but i cant make it work for unlimited lines, any help :(
Last edited by abc0502 on 30 Jul 2012 07:19, edited 1 time in total.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Shorten a function

#2 Post by foxidrive » 30 Jul 2012 05:15

In the following segment taken from the original file, will the parent page A number and the first child page number always be the same?

Code: Select all

NL/3,Black,notBold,notItalic,closed,TopLeftZoom,1,0,0.0        <parent page A
   KPI1/3,Black,notBold,notItalic,open,TopLeftZoom,213,8,0.0   <child page x
   KPI2/3,Black,notBold,notItalic,open,TopLeftZoom,469,8,0.0   <child page y
   KPI3/4,Black,notBold,notItalic,open,TopLeftZoom,63,8,0.0     <child page z

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Shorten a function

#3 Post by abc0502 » 30 Jul 2012 05:36

yes that's right

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Shorten a function

#4 Post by foxidrive » 30 Jul 2012 06:40

This works on the sample case but needs more testing on other cases.

You should have a lot of fun figuring out what it does. ;)
Ask if you need some description of a part and I'll see if I can explain what it does.

Sorry about the clumsy formatting - the board eats TAB characters. And the TAB in the code on line 8 has to be a real TAB character.


Code: Select all

@echo off
setlocal enabledelayedexpansion
set c=0
set bookmarksout=bookmarksout.txt
del "%bookmarksout%" 2>nul
for /f "tokens=1,2,* delims=/," %%a in ('type "bookmarks.txt"') do (
set "var=%%a"
if "!var:~0,1!"=="TAB" (
                              if defined flag (
                                             if !flag! LSS %%b (
                                             set /a c=c+1
                                             set flag=%%b
                                             >>"%bookmarksout%" echo %%a/!c!,%%c
                                      ) else (
                                             >>"%bookmarksout%" echo %%a/!c!,%%c
                                             )
                              ) else (
                                             set flag=%%b
                                             >>"%bookmarksout%" echo %%a/!c!,%%c
                              )
                  ) else (
                                 set "flag="
                                 set /a c=c+1
                                 >>"%bookmarksout%" echo %%a/!c!,%%c
               )
)

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Shorten a function

#5 Post by foxidrive » 30 Jul 2012 06:49

The above has had a few edits but should be ok now.

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Shorten a function

#6 Post by abc0502 » 30 Jul 2012 06:54

THANKS I NOTICED WHEN TESTING IT,and it is working great in many formats of the bookmarks file.
thanks again, and what is the "Flag" i don't get that

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Shorten a function

#7 Post by abc0502 » 30 Jul 2012 07:18

thanks again, the batch i was making was over 500 line and now with your code it reduce it with 253 line :)

thanks

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Shorten a function

#8 Post by foxidrive » 30 Jul 2012 07:28

It checks if the first character is a TAB to see if it is a child line and if it is then it will simply echo the "echo %%a/!c!,%%c" where the page number is the same as the previous parent line, and set the variable flag to the page number in the first child line.

Then on the next child line the flag is already set to something (saying that this is not the first child line) and flag cunningly serves a second purpose in keeping track of increments in the page number. If on the next child line or the following child line etc, it will check if the page number has changed with the comparison "if !flag! LSS %%b" and if it has changed then it will increment the counter c and then also remember the changed value in 'flag' variable, and echo out the new number in "echo %%a/!c!,%%c" If the page number hasn't change then it will keep the same counter number and echo the "echo %%a/!c!,%%c" with the info from the line.

If the first character is not a TAB, then it is a parent line, and the counter c is incremented, the flag variable is nulled to wait for the next child line, and the current counter and info is echoed in "echo %%a/!c!,%%c" once more.

I hope that isn't too confusing.

Code: Select all

if defined flag (
                                             if !flag! LSS %%b (
                                             set /a c=c+1
                                             set flag=%%b
                                             >>"%bookmarksout%" echo %%a/!c!,%%c
                                      ) else (
                                             >>"%bookmarksout%" echo %%a/!c!,%%c
                                             )
                              ) else (
                                             set flag=%%b
                                             >>"%bookmarksout%" echo %%a/!c!,%%c
                              )



thanks again, the batch i was making was over 500 line and now with your code it reduce it with 253 line


You're welcome. :)
Last edited by foxidrive on 30 Jul 2012 07:36, edited 1 time in total.

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Shorten a function [SOLVED]

#9 Post by abc0502 » 30 Jul 2012 07:34

i get the idea thank you. :)

Post Reply