变量
set myvar="c:\my music & videos"
myvar
将包含引号。实际上我认为这非常愚蠢。引号只是用来指示字符串的开始和结束位置,而不是作为值本身的一部分存储。我该如何防止这种情况发生? 谢谢。
变量
set myvar="c:\my music & videos"
myvar
将包含引号。实际上我认为这非常愚蠢。引号只是用来指示字符串的开始和结束位置,而不是作为值本身的一部分存储。set "myvar=c:\my music & videos"
注意引号是在 myvar 之前开始的。 这实际上很简单。 顺便说一句:如果没有用引号包围,就无法回显 myvar,因为 & 将被读取为命令分隔符,但它仍将作为路径工作。
http://ss64.com/nt/set.html 中的“变量名称可以包括空格”部分。
echo "%myvar%"
- Fowl这是正确的做法:
set "myvar=c:\my music & videos"
引号不会包含在变量值中。
这取决于您如何使用变量。如果您只想在不包括引号的情况下使用变量的值,则可以使用延迟扩展和字符串替换,或者使用 for
命令。
@echo OFF
SETLOCAL enabledelayedexpansion
set myvar="C:\my music & videos"
正如 andynormancx 所述,由于字符串包含 &
,因此需要引号。或者您可以使用 ^
进行转义,但我认为使用引号更加清晰。
如果您在字符串替换中使用延迟扩展,您将获得不带引号的变量值:
@echo !myvar:"=!
>>> C:\my music & videos
你也可以使用 for
命令:
for /f "tokens=* delims=" %%P in (%myvar%) do (
@echo %%P
)
>>> C:\my music & videos
然而,如果你想在命令中使用该变量,你必须使用带引号的值或将变量值用引号括起来:
使用字符串替代和延迟扩展,在不带引号的情况下使用变量的值,但在命令中使用该变量:
@echo OFF
SETLOCAL enabledelayedexpansion
set myvar="C:\my music & videos"
md %myvar%
@echo !myvar:"=! created.
使用for
命令可以不用引号使用变量值,但是在命令中使用变量时必须加上引号:
@echo OFF
set myvar="C:\my music & videos"
for /f "tokens=* delims=" %%P in (%myvar%) do (
md "%%P"
@echo %%P created.
)
长话短说,在批处理文件中使用包含空格和/或 &
的路径或文件名是没有一个干净的方法。使用jscript。
很久以前(约8年左右),我在一个大型C++/VB6项目上工作,我有各种批处理脚本来完成构建的不同部分。
然后有人向我指出了Joel测试,我特别喜欢第2点,并开始将所有小的构建脚本合并为一个单独的构建脚本...
这几乎让我心力憔悴,让所有这些小脚本在不同的机器上、具有稍微不同设置的情况下一起运行,设置变量和参数传递尤其困难。它非常脆弱,最轻微的事情都会导致它崩溃,并需要花费30分钟进行调整。
最终-我可以很固执-我把所有东西都扔掉了,用JavaScript重新编写了所有内容,并从命令提示符中使用CScript运行。
从那时起,我就没有回头看过去。虽然现在是MSBuild和Cruise Control,但如果我需要做任何稍微涉及到批处理脚本的事情,我就使用jscript。
Windows命令解释器允许您在整个set命令周围使用引号(适用于从NT 4.0到Windows 2012 R2的所有Windows NT版本)。
您的脚本应该按照以下方式编写:
@echo OFF
set "myvar=C:\my music & videos"
那么您可以根据需要在变量周围加上引号。
在CMD提示符下工作有时可能看起来很晦涩,但命令解释器实际上遵循其内部逻辑并表现得非常稳定,您只需要重新思考问题。
事实上,set命令根本不需要您使用引号,但是您变量赋值的方式以及不使用引号的方法都可能导致您的变量周围存在额外的空格,在调试脚本时很难注意到这一点。
例如,下面两种方式都是技术上有效的,但是您可能会有尾随空格,因此这不是一个好的做法:
set myvar=some text
set myvar="some text"
例如,以下两种方法都可以在Windows命令解释器中设置变量,但双引号方法更为优秀:
set "myvar=Some text"
(set myvar=Some value)
这两种方法都不需要解释,变量将会精确地包含你所需要的数据。
加粗文本 然而,基于你使用了保留字符,只有引用的方法才能有效。
因此,你应该使用:
set "myvar=c:\my music & videos"
然而,即使变量正确地设置为该字符串,当您ECHO字符串时,命令解释器将解释和符号为关键字,表示跟随另一个语句。
因此,如果要从变量中回显字符串,则仍需告诉CMD解释器它是文本字符串,或者如果不想显示引号,则必须执行以下操作之一:
用引号回显变量:
Echo."%myvar%"
输出变量但不包含引号:
Echo.%myvar:&=^&%
<nul SET /P="%myvar%"
C:\Admin> Echo.%myvar:&=^&%
C:\my music & videos
C:\Admin> <nul SET /P="%myvar%"
C:\my music & videos
C:\Admin>
echo(!myvar!
输出时不需要引号。 - jeb尝试使用转义字符'^',例如:
set myvar=c:\my music ^& videos
当你扩展myvar时,你必须小心,因为shell可能不会将&视为字面量。如果上述方法不起作用,请尝试在字符串中插入一个脱字符:
set myvar=c:\my music ^^^& videos
两种解决方案:
在路径名(目录或文件名)中不要使用空格或其他对命令解释器特殊的字符。如果您只使用字母、数字、下划线和连字符(以及在扩展名前面用句点标识文件类型),那么您的脚本编写生活将变得非常简单。
多年来,我编写并收集了大量工具,包括一个DOS实用程序,可以重命名文件。(它最初只是从文件名中删除空格的东西,但逐渐演变成可以在文件名中替换字符或字符串,甚至可以递归地进行。)如果有人感兴趣,我会把我的长期被忽视的网站重新启动并发布这个工具和其他工具。
话虽如此,变量不仅仅是用于保存路径名,所以...
正如其他人已经指出的那样,SET "myvar=c:\my music & videos" 是这种变量值的正确解决方法。(是的,我说的是解决方法。我同意您最初的想法只是引用该值("my music & videos"),但正如他们所说,它就是这样的。