0

I created th following text file which contains properties (properties.txt):

NAME=John
SURNAME=Blue
AGE=50

I have written a for loop in order to read line by line file (properties.txt). In this loop I call two function in order to read the PROPERTY_NAME and the PROPERTY_VALUE.

Everything is straight forward and easy, but I found out that although I get the right value in each of the functions, the result cannot be stored in the variable.

I provide you the following code in order to understand what I am talking about:

@ECHO OFF

SET PROPERTIES_FILE=properties.txt
SET PROPERTY_NAME=PROPERTY_NAME
SET PROPERTY_VALUE=PROPERTY_NAME

FOR /f "tokens=*" %%L IN (%PROPERTIES_FILE%) DO (
    CALL :GET_PROPERTY_NAME %%L
    CALL :GET_PROPERTY_VALUE %%L
    REM I get the wrong value. I actually get the initial values.
    REM WHY? How can I solve this?
    ECHO PROPERTY_NAME: %PROPERTY_NAME% PROPERTY_VALUE: %PROPERTY_VALUE%
)

GOTO END_OF_PROGRAM

:GET_PROPERTY_NAME
   SET PROPERTY_NAME=%~1
   REM I get the right value
   ECHO PROPERTY_NAME: %PROPERTY_NAME%
EXIT /B 0

:GET_PROPERTY_VALUE
   SET PROPERTY_VALUE=%~2
   REM I get the right value
   ECHO PROPERTY_VALUE: %PROPERTY_VALUE%
EXIT /B 0

:END_OF_PROGRAM

The Output of this code is:

PROPERTY_NAME: NAME
PROPERTY_VALUE: John
PROPERTY_NAME: PROPERTY_NAME PROPERTY_VALUE: PROPERTY_NAME
PROPERTY_NAME: SURNAME
PROPERTY_VALUE: Blue
PROPERTY_NAME: PROPERTY_NAME PROPERTY_VALUE: PROPERTY_NAME
PROPERTY_NAME: AGE
PROPERTY_VALUE: 50
PROPERTY_NAME: PROPERTY_NAME PROPERTY_VALUE: PROPERTY_NAME

The expected output should be:

PROPERTY_NAME: NAME
PROPERTY_VALUE: John
PROPERTY_NAME: NAME PROPERTY_VALUE: John
PROPERTY_NAME: SURNAME
PROPERTY_VALUE: Blue
PROPERTY_NAME: SURNAME PROPERTY_VALUE: Blue
PROPERTY_NAME: AGE
PROPERTY_VALUE: 50
PROPERTY_NAME: AGE PROPERTY_VALUE: 50

Does anybody know, why the value is not assigned from the function?

In case you know how to solve this issue, I will appreciate it.

aschipfl
  • 33,626
  • 12
  • 54
  • 99
Origamer7
  • 315
  • 3
  • 17
  • Why so complicated? Just use `for /F` with `delims==` to split property names and values: `for /F "usebackq tokens=1* delims== eol==" %%I in ("properties.txt") do echo Property name: %%I& echo Property value: %%J` (caveat: values must not begin with `=`)... – aschipfl Sep 16 '19 at 19:10

1 Answers1

1

Your issue is one of the most common answers under the [] tag on this site. Effectively when your block of code, (the ), is read both %PROPERTY_NAME% and %PROPERTY_VALUE% already have values which are expanded, i.e. PROPERTY_NAME. Because you're modifying those values within that code block, and wish to output the modified values within that same block, you need to delay that expansion. This is done by enabling delayed expansion, using SETLOCAL ENABLEDELAYEDEXPANSION and using the delayed expansion variable syntax which replaces %'s with !'s.

Example:

@ECHO OFF
SETLOCAL DISABLEDELAYEDEXPANSION

SET "PROPERTIES_FILE=properties.txt"
SET "PROPERTY_NAME=PROPERTY_NAME"
SET "PROPERTY_VALUE=PROPERTY_NAME"

FOR /F "USEBACKQ TOKENS=*" %%L IN ("%PROPERTIES_FILE%") DO (
    CALL :GET_PROPERTY_NAME %%L
    CALL :GET_PROPERTY_VALUE %%L
    SETLOCAL ENABLEDELAYEDEXPANSION
    ECHO PROPERTY_NAME: !PROPERTY_NAME! PROPERTY_VALUE: !PROPERTY_VALUE!
    ENDLOCAL
)

GOTO END_OF_PROGRAM

:GET_PROPERTY_NAME
SET "PROPERTY_NAME=%~1"
ECHO PROPERTY_NAME: %PROPERTY_NAME%
EXIT /B 0

:GET_PROPERTY_VALUE
SET "PROPERTY_VALUE=%~2"
ECHO PROPERTY_VALUE: %PROPERTY_VALUE%
EXIT /B 0

:END_OF_PROGRAM
REM The next line is added just to give you an opportunity to read the output.
PAUSE
Compo
  • 36,585
  • 5
  • 27
  • 39