1

I am trying to store a concatenated set of variables into a newly SET variable. When I add a variable into another variable it doesn't seem to actually get set correctly. I'm curious if BATCH can store variables within variables, or if I have to do formatting beyond what I currently have:

Example: The 'oldDirectory' variable should display the same thing as "%progdata%\%datetime%"

@echo off

For /f "tokens=2-4 delims=/ " %%a in ("%DATE%") do (
    SET YYYY=%%c
    SET MM=%%a
    SET DD=%%b
)
For /f "tokens=1-3 delims=/:." %%a in ("%TIME%") do (
    SET HH24=%%a
    SET MI=%%b
    SET SS=%%c
)

SET datetime=%YYYY%%MM%%DD%_%HH24%%MI%%SS%
SET progdata=C:\ProgramData

@echo on    

IF EXIST  "%progdata%" ( 
echo Found  %progdata%
SET oldDirectory="%progdata%\%datetime%"
echo %oldDirectory%
) 
pause

3 Answers 3

2

try with :

CALL SET oldDirectory="%progdata%\%datetime%"
CALL ECHO %oldDirectory%
Sign up to request clarification or add additional context in comments.

4 Comments

CALL SET is still leaving %oldDirectory% blank it appears.
I've edited the answer.With CALL SET you don't need double percent .But if you want to display the oldDirectory inside IF you'll need to use CALL ECHO
When trying your revised answer, it is still not listing anything for oldDirectory which to me indicates oldDirectory is empty?
It should not be...The example works on my machine , so I'm not sure where the problem can be.
2

First method:

IF EXIST  "%progdata%" ( 
echo Found  %progdata%
SET oldDirectory="%%progdata%%\%%datetime%%"
call echo %oldDirectory%
) 

Second method:

IF EXIST  "%progdata%" ( 
echo Found  %progdata%
SET oldDirectory="!progdata!\!datetime!"
setlocal EnableDelayedExpansion
echo %oldDirectory%
) 

An interesting point is that echo %oldDirectory% command display the current value of progdata and datetime variables with the same value of oldDirectory!

EDIT: Example added

@echo off

set progdata=C:\ProgramData

echo First method:
SET oldDirectory="%%progdata%%\%%date:/=%%_%%time::=%%"
call echo %oldDirectory%

echo Second method:
SET oldDirectory="!progdata!\!date:/=!_!time::=!"
setlocal EnableDelayedExpansion
echo %oldDirectory%

Output:

First method:
"C:\ProgramData\14082013_211303.20"
Second method:
"C:\ProgramData\14082013_211303.21"

2 Comments

When trying either of your suggestions my last call to display oldDirectory is blank. As its coded now I get a line back that states: ECHO is on.
@FuzzEvans: Be sure that the two variables have right values before use they in oldDirectory. See my added example above.
1

You have a standard DELAYED EXPANSION problem, discussed endlessly on SO.

When batch encounters a "Block statement" - that is typically a parenthesised statement spread over many lines such as your IF EXIST then the entire statement is parsed through to the closing parenthesis AND at this time, ANY %var% is replaced by the value of that variable as it stands WHEN THE STATEMENT IS PARSED

Consequently, your ECHO %olddirectory% is replaced by ECHO since olddirectory has no value AT PARSE TIME and executing ECHO will report ECHO is On/Off progdata on the other hand IS set at parse-time and hence echo Found %progdata% is replaced by echo Found C:\ProgramData

The very simplest cure is to move the ECHO statement outside of the block

IF EXIST  "%progdata%" ( 
 echo Found  %progdata%
 SET oldDirectory="%progdata%\%datetime%"
)
echo Olddirectory=%oldDirectory%

(I added the olddirectory= so that the echo statement finds something to echo if olddirectory is not set)

The second easiest way to display the value is

IF EXIST  "%progdata%" ( 
 echo Found  %progdata%
 SET oldDirectory="%progdata%\%datetime%"
 CALL echo %%oldDirectory%%
)

Here, the ECHO command is not expanded in the context of the IF, but in the context of the CALL which acquires its environment from the run-time value of the IF context.

The third easiest way to display the value is by using the delayedexpansion option of a setlocal command. An NT batch command traditionally starts

@echo off
setlocal

which suppresses echoing and establishes a local environment. Any changes to the local environment are backed out when an endlocal or end-of-file is reached in the setlocal's context. If this mantra is consistently followed, we don't get the situation where a variable is established by one batch and the environment is 'dirty' for the next. Consider running your original twice within the same cmd session. progdata, and all of the other variables you are establishing would remain set for the second coming - and hence olddirectory may be set by your first invocation, and retain that stale data if for some reason it's not EXPLICITLY set in the second. setlocal backs all those changes out for you.

setlocal enabledelayedexpansion adds an extra facility to the mix. Whereas %var% is resolved to the PARSE-TIME value of var, if delayedexpansion has been invoked then !var! is resolved to the RUN-TIME value - as it changes in a FOR loop...

Hence, adding

SETLOCAL ENABLEDELAYEDEXPANSION

at a strategic point (after the @echo off until you're off your training wheels...) would allow you to make a simple change to the display of olddirectory

IF EXIST  "%progdata%" ( 
 echo Found  %progdata%
 SET oldDirectory="%progdata%\%datetime%"
 echo !oldDirectory!
) 

1 Comment

I appreciated the in depth answer as to the problem including the solution. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.