Delayed expansion gives trouble with special character exclamationmark '!'

J

jihadmhaddad

Hi

I have delayed expansion set, which also means I can reference my
variables using exclamation marks (!var!) instead of percent (%var%).

However I have a problem assigning the special character
'!' (exclamation mark) to a list. Here is what happens. I want to make
a list containing string elements which contain exclamation marks, and
then I want to loop through that list.

The following code almost does what I need:
----------------------
@echo off
set list=( "elem1^!1" "elem2^!2" "elem4^!4" "elem3^!3" )
echo List using exclamation is !list!
echo List using percent is %list%
for %%i in !list! do (
echo %%i
)
----------------------

This gives the following output with error
----------------------
List using exclamation is ( "elem1!1" "elem2!2" "elem4!4" "elem3!3" )
List using percent is ( "elem12" "elem43" )
!list! was unexpected at this time.
----------------------

How do I reference my list so that I can loop through it?
I cannot use %list%, since this gives a wrong list, as can be seen in
the echo line "using percent".
I have all this trouble because I am using delayed expansion. I tried
turning it off for the example, and all went well using %%

I would appreciate any help I can get.
Jeeji
 
P

Pegasus [MVP]

Hi

I have delayed expansion set, which also means I can reference my
variables using exclamation marks (!var!) instead of percent (%var%).

However I have a problem assigning the special character
'!' (exclamation mark) to a list. Here is what happens. I want to make
a list containing string elements which contain exclamation marks, and
then I want to loop through that list.

The following code almost does what I need:
----------------------
@echo off
set list=( "elem1^!1" "elem2^!2" "elem4^!4" "elem3^!3" )
echo List using exclamation is !list!
echo List using percent is %list%
for %%i in !list! do (
echo %%i
)
----------------------

This gives the following output with error
----------------------
List using exclamation is ( "elem1!1" "elem2!2" "elem4!4" "elem3!3" )
List using percent is ( "elem12" "elem43" )
!list! was unexpected at this time.
----------------------

How do I reference my list so that I can loop through it?
I cannot use %list%, since this gives a wrong list, as can be seen in
the echo line "using percent".
I have all this trouble because I am using delayed expansion. I tried
turning it off for the example, and all went well using %%

I would appreciate any help I can get.
Jeeji

It's not quite clear what exactly you're trying to achieve, in part because
the output you quote does not agree with the code you post (the order of
lines is different!) but in general you can avoid the use of delayed
expansion by shifting part of the code into a subroutine. Here is an
example:

@echo off
SetLocal EnableDelayedExpansion
for /L %%a in (1,1,10) do (
set x=Number %%a
echo !x!
)
This is equivalent to:
@echo off
for /L %%a in (1,1,10) do call :Sub %%a
goto :eof

:Sub
set x=Number %*
echo %x%
 
A

Al Dunbar

Hi

I have delayed expansion set, which also means I can reference my
variables using exclamation marks (!var!) instead of percent (%var%).

However I have a problem assigning the special character
'!' (exclamation mark) to a list. Here is what happens. I want to make
a list containing string elements which contain exclamation marks, and
then I want to loop through that list.

The following code almost does what I need:
----------------------
@echo off
set list=( "elem1^!1" "elem2^!2" "elem4^!4" "elem3^!3" )
echo List using exclamation is !list!
echo List using percent is %list%
for %%i in !list! do (
echo %%i
)
----------------------

This gives the following output with error
----------------------
List using exclamation is ( "elem1!1" "elem2!2" "elem4!4" "elem3!3" )
List using percent is ( "elem12" "elem43" )
!list! was unexpected at this time.
----------------------

When I ran a copy, it produced this quite different output:

------------------------------
List using exclamation is !list!
List using percent is ( "elem1^!1" "elem2^!2" "elem4^!4" "elem3^!3" )
!list! was unexpected at this time.
------------------------------

When I added the requisite setlocal enabledelayedexpansion statement, this
resulted:

------------------------------
List using exclamation is ( "elem1!1" "elem2!2" "elem4!4" "elem3!3" )
List using percent is ( "elem12" "elem43" )
!list! was unexpected at this time.
------------------------------

The second line is correct, as it consists of a concatenation of:

literal string: ( "elem1
expansion of variable: !1" "elem2! since this is not defined the result is
null
literal string: 2" "elem4
expansion of variable: !4" "elem3! since this is not defined the result is
null
literal string: 3" )

If we take the parentheses out of the variable value and put it in the for
command, i.e.:

@echo off
setlocal enabledelayedexpansion
set list= "elem1^!1" "elem2^!2" "elem4^!4" "elem3^!3"
echo List using exclamation is !list!
echo List using percent is %list%
for %%i in (!list!) do (
echo %%i
)

the output becomes:

------------------------------
List using exclamation is "elem1!1" "elem2!2" "elem4!4" "elem3!3"
List using percent is "elem12" "elem43"
"elem11"
"elem22"
"elem44"
"elem33"
------------------------------

Now the for statement works, however, the exclamation marks have
disappeared. I suspect this is because, as emitted, they are no longer
escaped as special characters.
How do I reference my list so that I can loop through it?
I cannot use %list%, since this gives a wrong list, as can be seen in
the echo line "using percent".

Not so. As noted above, it simply gives a list that you did not expect. But
it did this precisely according to the rules.
I have all this trouble because I am using delayed expansion. I tried
turning it off for the example, and all went well using %%

I would appreciate any help I can get.

If % works, use %.

With delayed expansion on, the exclamation mark becomes a special character.
Just like the percent character. It works with % and delayed expansion off
because the exclamation is now treated as a regular character. Of course, if
it is a percent sign you want to use, that will be a special character and
give you similar difficulties.

String processing in batch is not particularly robust for another reasons,
one of which being the special characters. Rather than trying to force it to
work, it is usually more effective to find a way to avoid trying to process
or output special characters altogether.


/Al
 
B

billious

Hi

I have delayed expansion set, which also means I can reference my
variables using exclamation marks (!var!) instead of percent (%var%).

However I have a problem assigning the special character
'!' (exclamation mark) to a list. Here is what happens. I want to make
a list containing string elements which contain exclamation marks, and
then I want to loop through that list.

The following code almost does what I need:
----------------------
@echo off
set list=( "elem1^!1" "elem2^!2" "elem4^!4" "elem3^!3" )
echo List using exclamation is !list!
echo List using percent is %list%
for %%i in !list! do (
echo %%i
)
----------------------

This gives the following output with error
----------------------
List using exclamation is ( "elem1!1" "elem2!2" "elem4!4" "elem3!3" )
List using percent is ( "elem12" "elem43" )
!list! was unexpected at this time.
----------------------

How do I reference my list so that I can loop through it?
I cannot use %list%, since this gives a wrong list, as can be seen in
the echo line "using percent".
I have all this trouble because I am using delayed expansion. I tried
turning it off for the example, and all went well using %%

I would appreciate any help I can get.
Jeeji

I believe that you're oversimplifying and the example you give is quite
artificial. This appears to be trying to fix a solution to an unstated
problem, not a problem in itself.

Generally, I'd suggest that you retain the data in your loop-control
metavariables for as long as possible so they avoid evaluation, but without
knowing what data you're expecting and what you want to do with that data,
quite how to approach the problem is a guessing-game.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top