如何在 Windows cmd.exe 中正确转义文件名?

How to properly escape filenames in Windows cmd.exe?

如果你有一个包含 spaces 的文件名,你通常在 Windows 命令 shell (cmd.exe).

dir "\Program Files"

这也适用于其他特殊字符,如 ^&;,=。但它不适用于百分号,因为它们可能是变量替换的一部分。例如,

mkdir "%os%"

将创建一个名为 Windows_NT 的目录。要转义百分号,可以使用插入符号:

mkdir ^%os^%

但不幸的是,插入符号在双引号中失去了意义:

mkdir "^%os^%"

创建一个名为 ^%os^%.

的目录

这是我到目前为止发现的(Windows 7 命令shell):

这似乎使引用文件名的通用算法变得相当复杂。例如,要创建一个名为 My favorite %OS% 的目录,您必须这样写:

mkdir "My favorite "^%OS^%

问题 1:是否有更简单的方法来安全地引用 space 和百分比字符?

问题二:字符'`+-~_.!#$@()[]{}不用转义真的可以安全使用吗?

字符 ^& 可以用插入符号或双引号转义。

管道时有一个额外的限制。

When a pipe is used, the expressions are parsed twice. First when the expression before the pipe is executed and a second time when the expression after the pipe is executed. So to escape any characters in the second expression double escaping is needed:

The line below will echo a single & character:

break| echo ^^^&

字符 % 只能用脱字符转义。

%也可以加倍转义

The % character has a special meaning for command line parameters and FOR parameters.

To treat a percent as a regular character, double it:

%%


例如,要创建一个名为 My favorite %OS% 的目录,您必须这样写:

mkdir "My favorite "^%OS^%

Question 1: Is there an easier way to safely quote space and percent characters?

使用 %% 而不是 %,第二个 " 在您通常期望的末尾。

C:\test\sub>dir
...

 Directory of C:\test\sub

03/06/2015  14:40    <DIR>          .
03/06/2015  14:40    <DIR>          ..
               0 File(s)              0 bytes
               2 Dir(s)  82,207,772,672 bytes free

C:\test\sub>mkdir "My favorite %%OS%%"

C:\test\sub>dir
...
 Directory of C:\test\sub

03/06/2015  14:40    <DIR>          .
03/06/2015  14:40    <DIR>          ..
03/06/2015  14:40    <DIR>          My favorite %Windows_NT%
               0 File(s)              0 bytes
               3 Dir(s)  82,207,772,672 bytes free

Question 2: Are the characters '`+-~_.!#$@()[]{} really safe to use without escaping?

不,还有一些额外的情况,其中一些必须转义,例如使用延迟变量扩展或使用 for /f.

有关所有详细信息,请参阅 Escape Characters...尤其是摘要 table。


来源语法:转义字符、分隔符和引号Escape Characters


进一步阅读

  • How does the Windows Command Interpreter (CMD.EXE) parse scripts?