0

I'm trying to write a batch file to increment version number every time i run it, but I'm confuse about "for /f" and the behaviour of the batch file when I test it by using command prompt. Please help me with this. here's my batch file

for /f "tokens=2,3 " %%i in (version.h) do (
    set /a number=%%j+1
    echo %%i
    echo %%j
    echo %number%
    if %%i==REVISION (
        echo line1
        echo #define %%i "%number%" >> temp.file
    ) else (
        echo line2
        echo #define %%i %%j >> temp.file
    )
)
del /q version.h
ren temp.file version.h

and here's my version.h

#define MAJOR "1" 
#define MINOR "0" 
#define REVISION "242" 

The batch file can only produce correct result at the first run(#define REVISION "243"), and has a weird result at the second run(#define REVISION "0"). The third run's result is correct("#define REVISION "244"), but the forth run it goes weird again(#define REVISION "1"), and so on. It seems that I didn't parse the correct string so I cannot have correct result every time. I typed "for /?" in the command prompt and read the help message, but still cannot understand it, please help me with this. Any reply would be appreciate!

lesner
  • 25
  • 2

1 Answers1

0

The following script does what you want and preserves empty lines and special characters present in the target file. There is no temporary file involved, the file modification is accomplished in-place.

So here is the code -- reference the explanatory remarks for how it works:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "FILE=%~1" & rem // (provide the target file as command line argument)
set "DIRECTIVE=#define" & rem // (name of the directive to search)
set "DEFINITION=REVISION" & rem // (name of the definition to search)
set "CASESENS=" & rem // (set to non-empty for case-sensitive searches)
set "QUOTED="^" & rem // (set to non-empty for quoting returned number)

rem // Resolve arguments and options:
if not defined FILE ((>&2 echo ERROR: no file specified!) & exit /B 1)
if defined CASESENS (set "CASESENS=") else (set "CASESENS=/I")
if defined QUOTED (set "QUOTED="^") else (set "QUOTED=")

rem // Loop through all lines in the target file:
setlocal EnableDelayedExpansion
for /F delims^=^ eol^= %%L in ('
    rem/ /* Prefix lines with line numbers to not lose empty ones; ^& ^
    rem/    after having read file, deplete its entire content: */ ^& ^
    findstr /N /R "^^" "!FILE!" ^& ^> "!FILE!" break
') do (
    endlocal
    set "FLAG="
    set "LINE=%%L"
    rem // Split line into three tokens:
    for /F "tokens=1-3 eol= " %%I in ("%%L") do (
        set "FIELD1=%%I"
        set "FIELD2=%%J"
        set "NUMBER=%%~K"
        setlocal EnableDelayedExpansion
        rem // Check first token for matching directive name:
        if %CASESENS% "!FIELD1:*:=!"=="!DIRECTIVE!" (
        rem // Check second token for matching definition name:
            if %CASESENS% "!FIELD2!"=="!DEFINITION!" (
                endlocal
                rem // Increment number of third token:
                set /A "NUMBER+=1"
                set "FLAG=#"
                setlocal EnableDelayedExpansion
            )
        )
        endlocal
    )
    setlocal EnableDelayedExpansion
    rem // Write output line into target file:
    >> "!FILE!" (
        rem // Check whether dirctive and definition matched:
        if defined FLAG (
            rem // Match found, so write new line with incremented number:
            echo(!DIRECTIVE! !DEFINITION! %QUOTED%!NUMBER!%QUOTED%
        ) else (
            rem // No match found, so write original line:
            echo(!LINE:*:=!
        )
    )
)
endlocal

endlocal
exit /B
aschipfl
  • 33,626
  • 12
  • 54
  • 99