Computer Hope
Microsoft => Microsoft DOS => Topic started 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
-
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.
-
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 .
-
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?
-
Yes that is correct.
-
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?
@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%"
-
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.
#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.
-
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.
-
Try this - hopefully the comments do the explaining...
@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%"
-
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.
-
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)
-
winspear, this thread is being attacked by a troll and you should probably ignore any further comments from users you have not seen before.
-
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...
-
seems it's been fixed...
It's been fixed about 5 times today...
-
It is what it is. Let's stay with the thread please. Thanks.
-
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.
-
Okay Thanks. I'll lock it then.