HOWTO · Batch
How to Remove Double Quotes From a Variable in a Batch File
Learn when to use %~1, variable substitution, or FOR /F to remove surrounding or all double quotes in a Windows batch file.
On this page
Use %~1 when the quoted text is a batch-file argument. Use %variable:"=% when you intentionally want to remove every double-quote character from an environment variable. Use FOR /F with the %~A modifier when the value has one pair of surrounding quotes and the text inside them should remain unchanged. These are different operations, and choosing the wrong one is the main reason quote-removal examples fail.
The examples below use set "name=value" assignments so spaces after the equals sign do not become part of the value. They also show the expected result and the cases that require more care: ampersands and other command metacharacters, unmatched quotes, empty values, delayed expansion, and values changed inside a parenthesized block.
Remove quotes from a batch argument with %~1
Batch parameters %0 through %9 contain the script name and the arguments passed to it. If a caller writes an argument in double quotes so that a path or phrase containing spaces is passed as one item, the parameter includes those surrounding quotes. The tilde modifier removes that pair while expanding the parameter.
Create remove-quotes.cmd with this content:
@echo off
set "input=%~1"
echo Input without surrounding quotes: [%input%]
Run it with a quoted argument:
remove-quotes.cmd "Report 2026.txt"
Expected output:
Input without surrounding quotes: [Report 2026.txt]
%~1 is specifically a batch-parameter modifier. It does not mean “remove quotes from whatever variable is named by 1,” and it does not process an arbitrary environment variable. Use the corresponding modifier for each parameter, such as %~2 or %~3, when a script receives several quoted arguments. The modifier removes surrounding quotes; it does not remove quote characters embedded in the argument.
Remove every double quote from a variable
Variable substitution has a replacement form: %variable:search=replacement%. Replacing the double-quote character with an empty string removes every double quote that appears in the expanded value. This is useful when the input is known to use quotes as formatting characters and you deliberately want none of them in the result.
@echo off
set "value="Hello World""
set "withoutQuotes=%value:"=%"
echo Value: [%value%]
echo Without quotes: [%withoutQuotes%]
Expected output:
Value: ["Hello World"]
Without quotes: [Hello World]
This operation removes all quote characters, not only the first and last characters. For example, a value such as "Hello" "World" becomes Hello World; the quotes around each word are not preserved. It is therefore the wrong choice when quotation marks inside the value carry meaning.
The replacement syntax can replace other text as well. The following example changes one word without using a separate text-processing utility:
@echo off
set "value=Hello World"
set "updated=%value:World=Batch%"
echo [%updated%]
Expected output:
[Hello Batch]
Keep the assignment quoted as set "name=value". A value containing &, |, <, >, or ^ needs deliberate command-shell handling. The quotes around the set command protect the assignment form in common cases, but they do not turn arbitrary untrusted text into safe command code. Do not concatenate a cleaned value into a command line unless its characters and purpose are controlled.
Remove only surrounding quotes with FOR /F
When the value has one surrounding pair and embedded content must remain unchanged, use FOR /F and the %~A modifier. FOR /F reads the value as one line when delims= is supplied, and %~A removes surrounding quotes from the loop variable. In a batch file, the loop variable is written as %%A; at an interactive prompt it is written as %A.
@echo off
set "value="Hello World""
for /f "delims=" %%A in (%value%) do set "withoutOuter=%%~A"
echo Original: [%value%]
echo Without outer quotes: [%withoutOuter%]
Expected output:
Original: ["Hello World"]
Without outer quotes: [Hello World]
The delims= option prevents spaces from splitting the line into separate tokens. Without it, the default space and tab delimiters can cause only the first word to be captured. This method is aimed at one quoted line. It is not a general-purpose parser for arbitrary command text, and FOR /F has its own parsing rules for blank lines, delimiters, and special characters.
If the value might be empty, test that case explicitly. A FOR /F loop does not execute its body for every possible empty-input form, so the destination variable may remain undefined. Initialize it before the loop when an empty result must be distinguishable from an earlier value:
@echo off
set "value="
set "withoutOuter="
if defined value for /f "delims=" %%A in (%value%) do set "withoutOuter=%%~A"
if not defined withoutOuter echo The value is empty
Expected output:
The value is empty
Understand expansion timing in parenthesized blocks
Percent variables are expanded when cmd parses a command line or a parenthesized block. If a variable is changed earlier in the same block, a later %value% reference can still contain the value that existed when the block was parsed. Delayed expansion changes the timing, but it introduces ! as another special case.
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "value="Hello World""
set "withoutOuter="
for /f "delims=" %%A in (!value!) do set "withoutOuter=%%~A"
echo Without outer quotes: [!withoutOuter!]
endlocal
Expected output:
Without outer quotes: [Hello World]
Use delayed expansion only when the timing requires it, and remember that an exclamation mark in data can be consumed or changed while delayed expansion is enabled. For values that may contain !, keep the processing outside a delayed-expansion region or choose a design that does not expose the value to that parser phase.
Why quote removal is sometimes the wrong fix
Double quotes have two roles in a batch file. They can be syntax that keeps a path with spaces together when the command line is parsed, or they can be ordinary characters that were intentionally stored in a variable. The shell does not preserve a separate “these quotes were only for parsing” flag inside an environment variable. If a script assigns a value with set "path=C:\Program Files\Tool", the quotes in that form protect the assignment syntax and are not stored as part of the value. If it assigns set "path=\"C:\Program Files\Tool\"", the inner pair is data and must be removed deliberately.
This distinction explains why a variable may appear to contain quotes even though the original caller only wanted to pass one path. A caller can use quotes around an argument, while the receiving script uses %~1 to receive the path without that pair. If the script instead copies %1 into a variable, it copies the quoted representation. Removing the quotes later can work, but handling the parameter at the boundary is easier to reason about:
@echo off
set "path=%~1"
if not defined path (
echo A path argument is required.
exit /b 1
)
echo Ready to process: [%path%]
Expected output for process.cmd "C:\Program Files\Tool":
Ready to process: [C:\Program Files\Tool]
The if not defined check also separates an omitted argument from a value that happens to contain an empty pair of quotes. For scripts that accept user input, validate the resulting path or value before using it with del, copy, move, or another command. Quote removal is a string transformation; it does not make a path exist, normalize a path, or validate that the next command can safely consume it.
Choose the method deliberately
Use the following decision sequence when maintaining an existing script:
- If the input arrives through
%0through%9, remove only the outer argument quotes with the matching%~nmodifier. This is the simplest and most targeted operation. - If the value is an environment variable and every double quote is unwanted, use the replacement form
%name:"=%and assign the result with a quotedsetcommand. - If only one known outer pair should disappear while spaces and inner quote characters should remain, parse the line with
FOR /F "delims="and expand the loop variable with%~A. - If the value can contain metacharacters, exclamation marks, line breaks, or unmatched quotes, stop and define the input contract before adding a generic cleanup expression. A more complicated parser is not automatically safer.
When a value is passed to another command, keep the cleaned value separate from the command syntax. For example, storing C:\Program Files\Tool in a variable and using "%path%" at the point of use preserves the space-containing path. Removing quotes and then expanding the path without quotes can recreate the very parsing error that the cleanup was meant to solve.
Boundaries and troubleshooting
%~1 removes surrounding quotes from a parameter, while %variable:"=% removes every matching character from a variable. FOR /F with %~A is the more targeted choice for one outer pair, but it is still subject to FOR /F parsing. Do not use %~1 as a shortcut for a variable, and do not use global quote removal when inner quotes are meaningful.
Several common inputs need an explicit decision:
- A path with spaces normally needs quotes when it is passed as one argument. Remove those quotes only after the value has been separated from the command syntax.
- An unmatched quote is malformed input. Removing quote characters can hide the defect rather than repair the intended structure.
- An ampersand or another command metacharacter can change how a later command is parsed. Treat values from users or files as data, not as command fragments.
- A value can contain quotes as part of its content. Use outer-quote removal only when the boundary is known; otherwise document that all quote characters will be removed.
- A value changed in a parenthesized block may require delayed expansion, but delayed expansion changes the handling of exclamation marks.
- A batch file and an interactive command prompt use different
FORvariable spelling:%%Ain the file and%Aat the prompt.
The safest method is the narrowest one that matches the input: %~1 for a batch argument, FOR /F plus %~A for one surrounding pair, and replacement syntax only when every matching quote should be removed. Verify the cleaned value before using it in a file operation or another command.