Reputation: 63
I'm having a strange variable scope issue when trying to create a 'dos' (windows 7 command line) batch file which performs a bit of string manipulation to create new file paths. Can anyone see why the OUTPUT_FILENAME variable always ends up being null in the example below?
echo Enter the Data Input, S (Site) or U (User)
set /p DATA_TYPE=
echo.
echo Enter the Input File Name
set /p INPUT_FILENAME=
echo.
IF /I %DATA_TYPE%==u (
set OUTPUT_FILENAME=%INPUT_FILENAME:\users\=\Users\Outputs\%
set OUTPUT_FILENAME=%OUTPUT_FILENAME:xls=txt%
echo Output:
echo %OUTPUT_FILENAME%
)
IF /I %DATA_TYPE%==s (
set OUTPUT_FILENAME=%INPUT_FILENAME:\sites\=\Sites\Outputs\%
set OUTPUT_FILENAME=%OUTPUT_FILENAME:xls=txt%
echo Outputs:
echo %OUTPUT_FILENAME%
)
Thanks in advance for any assistance, this is driving me nuts!
Upvotes: 6
Views: 11237
Reputation: 70941
As Laf has correctly indicated, the code, as is, needs delayed expansion. In batch files, when a line or a block (all the lines enclosed in parenthesis) is reached, before being executed, it is parsed. In this parse phase, each variable read is replaced with the value the variable has before the execution starts.
If inside a block you change a variable, and want to access this changed value inside the same block, you need delayed expansion. The code in Laf answer reflect how to do it
Or, if it is possible, you can change your code to not need it
echo Enter the Data Input, S (Site) or U (User)
set /p DATA_TYPE=
echo.
echo Enter the Input File Name
set /p INPUT_FILENAME=
echo.
IF /I %DATA_TYPE%==u (
set OUTPUT_FILENAME=%INPUT_FILENAME:\users\=\Users\Outputs\%
)
IF /I %DATA_TYPE%==s (
set OUTPUT_FILENAME=%INPUT_FILENAME:\sites\=\Sites\Outputs\%
)
set OUTPUT_FILENAME=%OUTPUT_FILENAME:xls=txt%
echo Output:
echo %OUTPUT_FILENAME%
Now, there are variables changed inside blocks, but the values are then accessed out of the blocks.
Upvotes: 5
Reputation: 8215
You need to enable the delayed expansion:
setlocal EnableDelayedExpansion
echo Enter the Data Input, S (Site) or U (User)
set /p DATA_TYPE=
echo.
echo Enter the Input File Name
set /p INPUT_FILENAME=
echo.
SET OUTPUT_FILENAME=Empty
IF /I %DATA_TYPE%==u (
set OUTPUT_FILENAME=!INPUT_FILENAME:\users\=\Users\Outputs\!
set OUTPUT_FILENAME=!OUTPUT_FILENAME:xls=txt!
echo Output:
echo !OUTPUT_FILENAME!
)
IF /I %DATA_TYPE%==s (
set OUTPUT_FILENAME=!INPUT_FILENAME:\sites\=\Sites\Outputs\!
set OUTPUT_FILENAME=!OUTPUT_FILENAME:xls=txt!
echo Outputs:
echo !OUTPUT_FILENAME!
)
As the help for the SET
command states:
Delayed environment variable expansion is useful for getting around the limitations of the current expansion which happens when a line of text is read, not when it is executed.
So, you need to use the delayed expansion to make sure that INPUT_FILENAME
OUTPUT_FILENAME
's value are expanded at execution time.
Upvotes: 7