0

I'm trying to create a .bat program to replace two strings inside one text file and output the modified text multiple times.

So far so good...

The purpose of my program is to calculate the number of months between two dates (Ex: 01/2016 and 05/2017 will result in 17 months), and generate one configuration file for each month for a 3rd party program (17 output files in my example). This can be accomplished by replacing two tags ( and ) inside a template configuration file with the respective month/year values in that range.

My code so far is below:

@echo off &setlocal
setlocal ENABLEDELAYEDEXPANSION 
cls

set "CNST_SEARCH_YEAR=<VAR_YEAR>"
set "CNST_SEARCH_MONTH=<VAR_MONTH>"
set "CNST_FILE_TEMPLATE=config_template.properties"
set "CNST_FILE_TMP=tmp_config.properties"
rem ===============================
rem       INPUT DO USUÁRIO
rem ===============================
set "start_year=2014"
set "start_month=3"

set "end_year=2015"
set "end_month=7"

rem ===============================
rem DEFINIÇÂO DO TOTAL DE ITERAÇÕES
rem ===============================
set /a "iterations=(%end_year%*12 + %end_month%) - (%start_year%*12 + %start_month%) + 1"

echo DISPARO AUTOMATICO DA ROTINA AGENT - v1.0
echo ================================
echo      Total de iteracoes: %iterations%
echo ================================

rem ===============================
rem   EXECUÇÃO DO LOOP PRINCIPAL
rem ===============================
set v_year=%start_year%
set v_month=%start_month%
for /L %%i IN (1, 1, %iterations%) do (
    echo ================================
    echo Iteracao: %%i
    echo !v_year! / !v_month!

    echo Gerando parametrizacoes...
    for /f "delims=" %%j in (%CNST_FILE_TEMPLATE%) do (
        set "line=%%j"
        set "line=!line:%CNST_SEARCH_YEAR%=!v_year!"
        set "line=!line:%CNST_SEARCH_MONTH%=!v_month!"
        echo !line! >> "%CNST_FILE_TMP%_%%i"
    )

    echo Executando Agent...
    rem jre\bin\java.exe -jar gdc-agent-totvs-2.0.0.jar %CNST_FILE_TMP%

    echo Apagando arquivo temporario...
    rem del %CNST_FILE_TMP%

    IF !v_month! EQU 12 (
        set v_month=1
        set /a v_year=!v_year!+1
    ) ELSE (
        set /a v_month=!v_month!+1
    )

    echo ================================
)
endlocal

pause

My problem relies in the lines:

    set "line=!line:%CNST_SEARCH_YEAR%=v_year!"
    set "line=!line:%CNST_SEARCH_MONTH%=v_month!"

Because I can't use delayedExpansion multiple times inside that command. Also I can't define the v_year and v_month variables before the for loop, because their values are being set by the loop.

I'm using plain batch script since this program will be sent to other people who might not have powershell or other scripting tool.

Any ideas people?

Thanks.

mklement0
  • 245,023
  • 45
  • 419
  • 492

2 Answers2

0

You can try with something like

for %%v in (!v_year!) do set "line=!line:%CNST_SEARCH_YEAR%=%%v!"

This simply moves the delayed expanded value into a for replaceable parameter that can be used in the delayed expansion expression used in the set command

MC ND
  • 65,671
  • 6
  • 67
  • 106
  • Your solution also work, but I'll choose LotPings's answer because it makes more sense to me. The for loop wasn't made to bypass variable values :) – Diego Guedes Aug 16 '17 at 13:38
0

Or combine the old fashioned call variant

call set "line=%%line:!CNST_SEARCH_YEAR!=!v_year!%%"
call set "line=%%line:!CNST_SEARCH_MONTH!=!v_month!%%"

To escape a percent sign from being interpreted as enclosing a variable you have to double it. The parser reduces the two %% to a single one in this step.

The normal delayed expansion for the !var! is executed.

The call forces a second evaluation of the parser which find this time the single percent signs and acts on current values.

To learn more on this topic read How does the Windows Command Interpreter (CMD.EXE) parse scripts?

  • Your solution does work, but I don't understand why. Could you explain to me why you had to insert double %% and the call please? – Diego Guedes Aug 16 '17 at 12:44