Discussion forum for all Windows batch related topics.
Moderator: DosItHelp
-
lmstearn
- Posts: 50
- Joined: 07 Dec 2014 15:15
- Location: Australia
-
Contact:
#1
Post
by lmstearn » 31 Oct 2015 23:36
Just a note on Delayed Expansion (mentioned countless times before but...)
Code: Select all
@echo off & SETLOCAL ENABLEDELAYEDEXPANSION
SET _STRING=to be replaced
SET _NEWSTRING=not replaced
IF TRUE==TRUE (
SET "_NEWSTRING=!_STRING:to be r=r!"
@echo "%_STRING%" "%_NEWSTRING%"
pause >nul
) else (
@echo nada
pause >nul
)
@echo "%_STRING%" "%_NEWSTRING%"
pause >nul
The value of _NEWSTRING is not updated until the
IF sub exits. Can be an annoyance if debugging.
-
aGerman
- Expert
- Posts: 4678
- Joined: 22 Jan 2010 18:01
- Location: Germany
#2
Post
by aGerman » 01 Nov 2015 07:12
Imstearn wrote:@echo "%_STRING%" "%_NEWSTRING%"
As you should know the syntax of a variable will change if delayed expansion is defined. The reason for the delayed expansion is that you can access the current value of a variable that was changed in the same command line or the same (in parentheses enclosed) block of command lines. In that case you have to define delayed expansion and you have to
replace the percent signs with exclamation marks. Hence the question is where are the exclamation marks?
(EDIT: For whatever reason I deleted this post. So I just tried to remember the text that I wrote ...)
-
lmstearn
- Posts: 50
- Joined: 07 Dec 2014 15:15
- Location: Australia
-
Contact:
#3
Post
by lmstearn » 01 Nov 2015 08:44
Code: Select all
@echo off & SETLOCAL ENABLEDELAYEDEXPANSION
SET _STRING=to be replaced
SET _NEWSTRING=not replaced
IF TRUE==TRUE (
SET "_NEWSTRING=%_STRING:to be r=r%"
@echo "%_STRING%" "%_NEWSTRING%"
pause >nul
) else (
@echo nada
pause >nul
)
@echo "%_STRING%" "%_NEWSTRING%"
pause >nul
The same effect. The aim is to
avoid bangs for the moment.
-
aGerman
- Expert
- Posts: 4678
- Joined: 22 Jan 2010 18:01
- Location: Germany
#4
Post
by aGerman » 01 Nov 2015 08:56
The question remains the same...
aGerman wrote:where are the exclamation marks?
Something to play with:
Code: Select all
@echo off &setlocal EnableDelayedExpansion
set "var=0"
echo before: %var%
echo ~~~~
for /l %%i in (1 1 10) do (
set "var=%%i"
echo with percent signs: %var%
echo with exclamation marks: !var!
echo ~~~~
)
echo after: %var%
pause
The body of a loop or of an if statement
is a block of command lines that is enclosed into parentheses. Please reread my first reply.
BTW a proper line indentation will help you to realize that you are in a block of command lines and it will help to avoid unpaired parentheses.
Regards
aGerman
-
Aacini
- Expert
- Posts: 1914
- Joined: 06 Dec 2011 22:15
- Location: México City, México
-
Contact:
#5
Post
by Aacini » 01 Nov 2015 13:38
lmstearn wrote: The aim is to avoid bangs for the moment.
This should work
Code: Select all
@echo off
SET _STRING=to be replaced
SET _NEWSTRING=not replaced
IF TRUE==TRUE (
CALL SET "_NEWSTRING=%%_STRING:to be r=r%%"
@CALL echo "%%_STRING%%" "%%_NEWSTRING%%"
pause >nul
) else (
@echo nada
pause >nul
)
@echo "%_STRING%" "%_NEWSTRING%"
pause >nul
HOWEVER if previous code will be executed in the command-line context, I think you must change the double percents by single ones. You must do a test on this point!
Antonio
-
foxidrive
- Expert
- Posts: 6031
- Joined: 10 Feb 2012 02:20
#6
Post
by foxidrive » 01 Nov 2015 22:10
lmstearn wrote:The aim is to
avoid bangs for the moment.
Bangs is what you do in dodgem cars. Your linked post made no sense to me, using the word bangs.
-
lmstearn
- Posts: 50
- Joined: 07 Dec 2014 15:15
- Location: Australia
-
Contact:
#7
Post
by lmstearn » 01 Nov 2015 22:53
That's fine. The only thing that puzzles is that the
static nomenclature hasn't been revised in years. I'm sure there was an ancient blurb that explained it all, but
delayed expansion? Without using bangs the expansion is taken to the first point outside the sub. "Delayed" expansion as opposed to "instantaneous" expansion.
Something like "execute_expansion" an improvement?
-
lmstearn
- Posts: 50
- Joined: 07 Dec 2014 15:15
- Location: Australia
-
Contact:
#9
Post
by lmstearn » 03 Nov 2015 04:22
Yeah, Aacini's example posted above is what I consider a classic case of "delayed expansion" without it ever turned on.
But TBQH the material collated on this, and related topics on cmd in this site and SO amounts are quite voluminous. Sites like Robvandwoude and SS64 also give pretty good coverage, but
encore, encore!
Case in point is the post you quoted, but that alone can be expanded (along with illustrative examples) to fill a good sized book.
-
Samir
- Posts: 384
- Joined: 16 Jul 2013 12:00
- Location: HSV
-
Contact:
#10
Post
by Samir » 07 Nov 2015 11:25
Delayed expansion can be a real bane for me. Always great to see refreshes on the subject.
-
aGerman
- Expert
- Posts: 4678
- Joined: 22 Jan 2010 18:01
- Location: Germany
#11
Post
by aGerman » 07 Nov 2015 11:48
Have a look at my examples at the end of this thread:
viewtopic.php?f=3&p=36882aGerman wrote:Rough rule of thumb:
Assigning a variable is safe with delayed expansion disabled. Working with the assigned variable is safe with delayed expansion enabled.
-
Samir
- Posts: 384
- Joined: 16 Jul 2013 12:00
- Location: HSV
-
Contact:
#12
Post
by Samir » 07 Nov 2015 15:57
aGerman wrote:Have a look at my examples at the end of this thread:
viewtopic.php?f=3&p=36882aGerman wrote:Rough rule of thumb:
Assigning a variable is safe with delayed expansion disabled. Working with the assigned variable is safe with delayed expansion enabled.
Will do!
Rule of thumb for me is--if there's a problem, use a bunch of echos to figure out what's wrong.
-
trebor68
- Posts: 146
- Joined: 01 Jul 2011 08:47
#13
Post
by trebor68 » 07 Nov 2015 16:51
Your code updated.
Code: Select all
@echo off & SETLOCAL ENABLEDELAYEDEXPANSION
SET _STRING=to be replaced
SET _NEWSTRING=not replaced
IF TRUE==TRUE (
SET "_NEWSTRING=%_STRING:to be r=r%"
echo "%_STRING%" "%_NEWSTRING%" ## "%_STRING%" "!_NEWSTRING!"
IF "!_NEWSTRING!"=="replaced" (echo The string is replaced.) & echo.
pause >nul
) else (
echo nada
pause >nul
)
echo "%_STRING%" "%_NEWSTRING%"
pause >nul
The variable
%_NEWSTRING% is only changed when the IF construct is exited (delayed).
The variable
!_NEWSTRING! is varied within the IF construct.