Dealing with quotes in Windows batch scripts

106,310

Solution 1

set "myvar=c:\my music & videos"

Notice the quotes start before myvar. It's actually that simple. Side note: myvar can't be echoed afterwards unless it's wrapped in quotes because & will be read as a command separator, but it'll still work as a path.

http://ss64.com/nt/set.html under "Variable names can include Spaces"

Solution 2

This is the correct way to do it:

set "myvar=c:\my music & videos"

The quotes will not be included in the variable value.

Solution 3

It depends on how you want to use the variable. If you just want to use the value of the variable without the quotes you can use either delayed expansion and string substitution, or the for command:

@echo OFF
SETLOCAL enabledelayedexpansion

set myvar="C:\my music & videos"

As andynormancx states, the quotes are needed since the string contains the &. Or you can escape it with the ^, but I think the quotes are a little cleaner.

If you use delayed expansion with string substitution, you get the value of the variable without the quotes:

@echo !myvar:"=!
>>> C:\my music & videos

You can also use the for command:

for /f "tokens=* delims=" %%P in (%myvar%) do (
    @echo %%P
)
>>> C:\my music & videos

However, if you want to use the variable in a command, you must use the quoted value or enclose the value of the variable in quotes:

  1. Using string substitution and delayed expansion to use value of the variable without quotes, but use the variable in a command:

    @echo OFF
    SETLOCAL enabledelayedexpansion
    
    set myvar="C:\my music & videos"
    md %myvar%
    @echo !myvar:"=! created.
    
  2. Using the for command to use the value of the variable without quotes, but you'll have to surround the variable with quotes when using it in commands:

    @echo OFF
    set myvar="C:\my music & videos"
    
    for /f "tokens=* delims=" %%P in (%myvar%) do (
        md "%%P"
        @echo %%P created.
    )
    

Long story short, there's really no clean way to use a path or filename that contains embedded spaces and/or &s in a batch file.

Solution 4

Use jscript.

Many moons ago (i.e. about 8 years give or take) I was working on a large C++/VB6 project, and I had various bits of Batch Script to do parts of the build.

Then someone pointed me at the Joel Test, I was particularly enamoured of point 2, and set about bringing all my little build scripts into one single build script . . .

and it nearly broke my heart, getting all those little scripts working together, on different machines, with slightly different setups, ye Gods it was dreadful - particularly setting variables and parameter passing. It was really brittle, the slightest thing would break it and require 30 minutes of tweaking to get going again.

Eventually - I can be stubborn me - I chucked the whole lot in and in about a day re-wrote it all in JavaScript, running it from the command prompt with CScript.

I haven't looked back. Although these days it's MSBuild and Cruise Control, if I need to do something even slightly involved with a batch script, I use jscript.

Solution 5

The Windows command interpreter allows you to use the quotes around the entire set command (valid in every version of windows NT from NT 4.0 to Windows 2012 R2)

Your script should just be written as follows:

@echo OFF

set "myvar=C:\my music & videos"

Then you may put quotes around the variables as needed.

Working with the CMD prompt can seem esoteric at times, but the command interpreter actually behaves pretty solidly in obeying it's internal logic, you just need to re-think things.

In fact, the set command does not require you to use quotes at all, but both the way you are doing your variable assignment and the way the ,method of using no quotes can cause you to have extra spaces around your variable which are hard to notice when debugging your script.

e.g. Both of the below are technically Valid, but you can have trailing spaces, so it's not a good practice:

set myvar=some text   
set myvar="some text" 

e.g. Both of the below are good methods for setting variables in Windows Command interpreter, however the double quote method is superior:

set "myvar=Some text"
(set myvar=Some value)

Both of these leave nothing to interpretation the variable will have exactly the data you are looking for.

strong text However, for your purposes, only the quoted method will work validly because you are using a reserved character

Thus, you would use:

set "myvar=c:\my music & videos"

However, even though the variable IS correctly set to this string, when you ECHO the sting the command interpreter will interpret the ampersand as the keyword to indicate another statement follows.

SO if you want to echo the string from the variable the CMD interpreter still needs to be told it's a text string, or if you do not want the quotes to show you have to do one of the following:

echo the variable WITH Quotes:

Echo."%myvar%"

echo the variable WITHOUT Quotes:

Echo.%myvar:&=^&%
<nul SET /P="%myvar%"

In the above two scenarios you can echo the string with no quotes just fine. Example output below:

C:\Admin>    Echo.%myvar:&=^&%
C:\my music & videos

C:\Admin>    <nul SET /P="%myvar%"
C:\my music & videos
C:\Admin>
Share:
106,310
Berkyjay
Author by

Berkyjay

Updated on July 05, 2022

Comments

  • Berkyjay
    Berkyjay almost 2 years

    In a Windows batch file, when you do the following:

    set myvar="c:\my music & videos"

    the variable myvar is stored with the quotes included. Honestly I find that very stupid. The quotes are just to tell where the string begins and ends, not to be stored as part of the value itself.
    How can I prevent this from happening?

    Thanks.

  • Tomalak
    Tomalak over 15 years
    Not really an answer to the question, but since I already have been to the la-la-land of cmd.exe string escaping inside and outside of batch files, I totally agree with you. +1
  • Rabeel
    Rabeel over 15 years
    Excellent answer . . . but it made my head hurt . . .
  • Patrick Cuff
    Patrick Cuff over 15 years
    @Binary Worrier; yeah, batch files tend to do that ;)
  • andynormancx
    andynormancx over 15 years
    You must be some sort of batch file God. Such glorious clever idiocy ;)
  • Jay Sullivan
    Jay Sullivan about 10 years
    This is awesome. Did not know about this.
  • user
    user almost 10 years
    Very useful, though this answer deserves the credit stackoverflow.com/a/8582277/781695
  • Rabeel
    Rabeel over 9 years
    Goes without saying that these days it's all Powershell.
  • Raymond
    Raymond over 9 years
    @BinaryWorrier Mental, surely you'd get with the times and use FAKE ? (Not actually joking BTW, it's great) (Disclaimer: have not 100% ascertained that you and/or OP are talking about build scripts - just here on a stalker basis!)
  • Fowl
    Fowl over 8 years
    it can actually be echoed, you just have to wrap it in quotes ;) echo "%myvar%"
  • binki
    binki over 8 years
    @Fowl but then the doublequotes get echoed too.
  • jeb
    jeb over 7 years
    You can always use a variable in a safe way with delayed expansion. echo(!myvar! This doesn't needs quotes for the output
  • Matthieu
    Matthieu about 5 years
    How is your answer any different than @RuskoGuyachev's that was written one year earlier?
  • caduceus
    caduceus almost 4 years
    if you wrap the path to an executable like this, you will need to quote it on invocation "%msbuild%"
  • et_phonehome
    et_phonehome about 3 years
    Much clearer "The quotes will not be included in the variable value."