26

I have a variable that contains ampersands and I need to create another variable that contains the first one. I know the "&" character can be escaped with carret (^) but I have no idea how to escape the text inside a variable.

set Name1 = Red ^& Green
set Name2 = %Name1% ^& Blue

'Green' is not recognized as an internal or external command, operable program or batch file.

I can't even "echo" the variables containing ampersands - I get the same error.

I need to use the variables in order to type their contents to the output or to manipulate files named by the variables like

type "%Name1%.txt"
type "%Name2%.txt"
Community
  • 1
  • 1
BearCode
  • 2,734
  • 6
  • 34
  • 37

4 Answers4

25

The simplest solution is to use quotes for the assignment, and delayed expansion. This eliminates any need for escaping.

@echo off
setlocal enableDelayedExpansion
set "Name1=Red & Green"
set "Name2=!Name1! & Blue"
echo !Name2!

If you have a mixture of quoted and unquoted text, you sometimes must escape some characters. But that is only needed for the initial assignment. The content of a variable never needs to be escaped when using delayed expansion.

@echo off
setlocal enableDelayedExpansion
set var="This & that" ^& the other thing.
echo !var!
dbenham
  • 127,446
  • 28
  • 251
  • 390
  • 1
    using enableDelayedExpansion allows me to make use of the variables. Therefore -> type "%Name1%.txt" <- works. For the moment this looks like the best solution. Thanks – BearCode Jan 01 '13 at 08:39
  • @dbenham Thanks for that. I was in the exact same situation, and your answer came to rescue. However, although I thought I knew what `EnableDelayedExpansion` is doing and what it is meant for, in this case for the life of me I don't get why it is needed here and why it doesn't work without it. Could you please shortly elaborate or provide a link? – Binarus Dec 28 '19 at 17:09
  • 3
    @Binarus - It is not needed in the `set "Name2=...` statement, but nor does it cause a problem. `"set Name2=%Name1% & Blue"` would work just as well because of the quotes. Delayed expansion is needed in the `echo !Name2!` to protect the `&` characters. If delayed expansion is enabled and a variable value may contain `!` then `!var!` should always be used instead of `%var%` else the `!` will be stripped from the content. – dbenham Dec 28 '19 at 18:03
  • 1
    @dbenham Thank you very much for that precise explanation. Got it! – Binarus Dec 28 '19 at 18:54
9

Unfortunately, you will have to double escape the ampersands since it is being evaluated twice or place the variable value in quotations.

set Name1=Red ^^^& Green
set Name2=%Name1% ^& Blue

But you will also need to add another set of escapes for when Name2 gets used. Which gets to be a major pain.

set Name1=Red ^^^^^& Green
set Name2=%Name1% ^^^& Blue

Or use quotations (Recommended)

set "Name1=Red ^& Green"
set "Name2=%Name1% ^& Blue"
David Ruhmann
  • 11,064
  • 4
  • 37
  • 47
0

Two solutions come to mind, neither of which is sufficiently general, but they both "work":

  1. Always keep things in quotes and remove them when you need to, as noted in the previous solution.
  2. Re-quote the &'s: set name2=%name1:&=^&% ^& Blue
MJZ
  • 1,074
  • 6
  • 12
-2

The simplest solution would be this one:

for /f "delims= usebackq" %a in (`echo "First & ? * Last"`) do echo # %~a

...in a batch script:

for /f "delims= usebackq" %%a in (`echo "First & ? * Last"`) do echo # %%~a

or

for /f "delims= usebackq" %%a in (`echo "%~1"`) do echo # %%~a
Jaroslav Záruba
  • 4,694
  • 5
  • 39
  • 58
  • 1
    This does not answer the question, which is about environment variables – dbenham May 19 '17 at 14:07
  • Where on this page is the word "environment" even mentioned? Unlike your answer mine actually does involve input parameter. Yours only works with hardcoded strings. I see someone is a bit bitter here... – Jaroslav Záruba May 19 '17 at 16:28
  • And of course my solution works even for environmental variables, there is no difference, nothing special about them. And you know that very well. – Jaroslav Záruba May 19 '17 at 16:31
  • 1
    The OP's text explicitly talks about variables, and his example code makes it obvious he is working with environment variables. My code is a demonstration of a concept, not a plug-and-play solution. You should re-read the question and note how my code demonstrates how to properly accomplish what the OP tried to do in his. Your answer never demonstrates how to safely embed variable content within the definition of another. Your "bitter" comment is ironic. – dbenham May 19 '17 at 17:05
  • Sure, you can expand a variable within the IN() clause, but that does not buy anything toward solving this problem that cannot be solved without FOR. Your FOR will fail if the string value contains `?` or `*`. You could switch to FOR /F, but then you may need to worry about disabling both DELIMS and EOL, which is very awkward syntax. – dbenham May 19 '17 at 17:07
  • Works with ?, & and *. Still way simpler and single line. But I do understand the situation. :) – Jaroslav Záruba May 19 '17 at 18:36