Computer Hope

Microsoft => Microsoft DOS => Topic started by: winspear on April 28, 2011, 12:30:27 PM

Title: Using BATCH file: Find a number inside a file and increment it
Post by: winspear on April 28, 2011, 12:30:27 PM
Hi,
I am trying to automate the build system of one of the softwares and I want to read a particular number in a file and increment it. How do I achieve this using batch files.
So far I am able to find the line in which this number resides in a file using findstr. Now I want to icrement it and write it back.

Any help will be appreciated.
Thanks
Title: Re: Using BATCH file: Find a number inside a file and increment it
Post by: Salmon Trout on April 28, 2011, 12:52:57 PM
We cannot look at your computer's files and see how the number occurs in the file, since you have not seen fit to give any example, so only very general advice will be possible. A possible approach might be

Choose a temporary file name. If the file exists, delete it.

Iterate through the file to be processed using FOR /F, checking each line using findstr to see if it is the one containing the number. Note that blank lines and lines starting with a space or a semicolon will not be processed.

If it is not the number line, write it out straight away to the temporary file using the append redirection operator.

When the line containing the number is reached, process that line using FOR with a suitable set of delims= and tokens= directives to isolate (1) the number (2) the rest of that line.

Put the number into a variable, increment it using set /a then write out the complete line with the incremented number in place of the previous one again using the append operator.

When all the lines of the original file have been processed, delete the original file and rename the temporary file with the original file's name.

 
Title: Re: Using BATCH file: Find a number inside a file and increment it
Post by: winspear on April 28, 2011, 12:58:33 PM
Sorry for not being specific. Here is a sample file say version.hand here are the contents of the file.

Version.h contents


#define VERSION_MAJOR_NUMBER            3
#define VERSION_MINOR_NUMBER            10
#define VERSION_BUILD_NUMBER            02


I want to increment the major and minor version number by 2 and save the file .
Title: Re: Using BATCH file: Find a number inside a file and increment it
Post by: Salmon Trout on April 28, 2011, 01:06:33 PM
I note that the VERSION_MAJOR_NUMBER is shown as a single digit number ('3') whereas VERSION_BUILD_NUMBER is shown with a leading zero ('02'). However I note that you only require that VERSION_MAJOR_NUMBER and VERSION_MINOR_NUMBER are to be altered, so I am presuming that there will be no leading zeroes required?




Title: Re: Using BATCH file: Find a number inside a file and increment it
Post by: winspear on April 28, 2011, 01:25:11 PM
Yes that is correct.
Title: Re: Using BATCH file: Find a number inside a file and increment it
Post by: Salmon Trout on April 28, 2011, 01:34:22 PM
If those 3 lines are the only lines that will be in version.h, then this seems to work. Will there be other lines in the file? Is this the only file you wish to process?

Code: [Select]
@echo off
setlocal enabledelayedexpansion
set filename=version.h
if exist "%filename%.temp" del "%filename%.temp"
for /f "tokens=1-3 delims= " %%A in (version.h) do (
if "%%B"=="VERSION_MAJOR_NUMBER" (
set num=%%C
set /a num+=1
echo READ:  %%A %%B            %%C
echo WRITE: %%A %%B            !num!
echo.
echo %%A %%B            !num!>>"%filename%.temp"
)
if "%%B"=="VERSION_MINOR_NUMBER" (
set num=%%C
set /a num+=1
echo READ:  %%A %%B            %%C
echo WRITE: %%A %%B            !num!
echo.
echo %%A %%B            !num!>>"%filename%.temp"
)
if "%%B"=="VERSION_BUILD_NUMBER" (
echo READ:  %%A %%B            %%C
echo WRITE: %%A %%B            %%C
echo.
echo %%A %%B            %%C>>"%filename%.temp"
)
)
del "%filename%"
ren "%filename%.temp" "%filename%"
Title: Re: Using BATCH file: Find a number inside a file and increment it
Post by: winspear on April 28, 2011, 01:48:10 PM
Wow. Thanks that was fast. Currently only these three lines are there in the file. But it will be worthwhile for me to learn an approach for a file with more nuber of lines in them. I would definitely like to see the approach you take in that instance.
Lets say same file version.h  but with more content like.
Code: [Select]
#ifndef MY_DEFINES_H_DEFINE
#define MY_DEFINES_H_DEFINE

#include <limits.h>

/* Boolean */
#define MY_TRUE                           1
#define MY_FALSE                          0

/******************************************************************************
 * Version information                                                        */

#define VERSION_MAJOR_NUMBER            3
#define VERSION_MINOR_NUMBER            10
#define VERSION_BUILD_NUMBER            02

/* Version information end                                                    *
*******************************************************************************/

/******************************************************************************
 * Error codes                                                                */

#define MY_SUCCESS                         0x0000

/* Function errors */
#define MY_FAILURE                          0x0100

/* Error codes end                                                           *****************************************************************************/

#endif  /* MY_DEFINES_H_DEFINE */
/******************************************************************************/


Thanks once again for the quick reply.
Title: Re: Using BATCH file: Find a number inside a file and increment it
Post by: Salmon Trout on April 28, 2011, 02:37:45 PM
The next reply won't be so quick; it is late evening here in England; I will soon be in bed; however tomorrow I will sketch something out.
Title: Re: Using BATCH file: Find a number inside a file and increment it
Post by: Salmon Trout on April 29, 2011, 08:16:39 AM
Try this - hopefully the comments do the explaining...

Code: [Select]
   @echo off
   REM you need this to set and read a variable inside
   REM a parethetical structure such as a FOR loop
   setlocal enabledelayedexpansion

   REM This is the file we are going to alter
   set filename=version.h
   
   REM Use temp file
   REM delete if already exists
   REM so we can use append operator for all output
   if exist "%filename%.temp" del "%filename%.temp"
   
   REM For each line in the file...
   REM ...using FOR alone to parse the file skips blank lines so we...
   REM ...parse the output (note single quotes) of...
   REM running TYPE on the file and piping the output through FINDSTR...
   REM ...with the /n switch (this adds a line number and a colon at the start of each line)
   REM the FINDSTR search string is ".*" (find any characters including cr/lf)
   REM Split into 2* tokens, the asterisk means %%R is the entire remainder of the line
   REM delimiter being the colon thus...
   REM The number is token 1, %%Q (discarded, along with the colon)
   REM The original source file line is token 2, %%R
   REM note we escape the pipe character with a caret ^ in the FOR dataset block
   for /f "tokens=1,2* delims=:" %%Q in ('type "%filename%" ^| findstr /n ".*"') do (
   
      REM if token 2 is null then the line is blank so we echo a blank line to the temp output file
      if "%%R"=="" echo. >> "%filename%.temp"
     
      REM This flag gets set to 1 if we have a line that needs changing
      set incflag=0
     
      REM Split the line into 3 tokens with white space the delimiter
      for /f "tokens=1-3 delims= " %%A in ("%%R") do (
     
         REM test if an increment needs to happen and set the flag if it does
         if "%%B"=="VERSION_MAJOR_NUMBER" set incflag=1
         if "%%B"=="VERSION_MINOR_NUMBER" set incflag=1
         REM %%C is the number
         
         REM If the line contains a number to increment...
         if !incflag! equ 1 (
            REM do it...
            set /a num=%%C+1
           
            REM info msg to console
            echo Incrementing %%B from %%C to !num!
           
            REM write the altered line to file
            echo %%A %%B            !num!>>"%filename%.temp"
         
         REM the line is a nonblank one that simply needs copying   
         ) else (

            echo %%R >> "%filename%.temp"

         REM Match those parentheses!
         )
      )
   )

   REM delete original file
   del "%filename%"
   
   REM rename temp file to original file name
   ren "%filename%.temp" "%filename%"
Title: Re: Using BATCH file: Find a number inside a file and increment it
Post by: winspear on April 29, 2011, 09:17:10 AM
Thats perfect. Both the codes work like a charm.
Now I completely understand how to parse through a file and edit certain sections using tokens.
Thanks for all your help Salmon Trout.
Title: Re: Using BATCH file: Find a number inside a file and increment it
Post by: Salmon Trout on April 30, 2011, 11:48:08 AM
Code: [Select]
REM write the altered line to file
            echo %%A %%B            !num! >>"%filename%.temp"

I think you should add a space after !num! (as above) to avoid any problems with stream redirection if the final digit of !num! is a 1 or 2 (It's to do with stdout [console stream 1] and stderr [console stream 2] redirection)


Title: Re: Using BATCH file: Find a number inside a file and increment it
Post by: Salmon Trout on May 01, 2011, 01:56:05 PM
winspear, this thread is being attacked by a troll and you should probably ignore any further comments from users you have not seen before.
Title: Re: Using BATCH file: Find a number inside a file and increment it
Post by: BC_Programmer on May 01, 2011, 01:58:28 PM
winspear, this thread is being attacked by a troll and you should probably ignore any further comments from users you have not seen before.

seems it's been fixed...
Title: Re: Using BATCH file: Find a number inside a file and increment it
Post by: Salmon Trout on May 01, 2011, 02:41:01 PM
seems it's been fixed...

It's been fixed about 5 times today...
Title: Re: Using BATCH file: Find a number inside a file and increment it
Post by: Allan on May 01, 2011, 02:47:25 PM
It is what it is. Let's stay with the thread please. Thanks.
Title: Re: Using BATCH file: Find a number inside a file and increment it
Post by: Salmon Trout on May 01, 2011, 04:34:59 PM
It is what it is. Let's stay with the thread please. Thanks.

Essentially, this thread is now complete. The OP expressed a requirement which was clarified and then addressed, despite frequent attempts at interference, to the OP's expressed satisfaction.
Title: Re: Using BATCH file: Find a number inside a file and increment it
Post by: Allan on May 01, 2011, 04:38:30 PM
Okay Thanks. I'll lock it then.