在 Windows 批处理文件中,当您执行以下操作时:
set myvar="c:\my music & videos"
该变量myvar
与包含的引号一起存储。老实说,我觉得这很愚蠢。引号只是说明字符串的开始和结束位置,而不是作为值本身的一部分存储。
我怎样才能防止这种情况发生?
谢谢。
在 Windows 批处理文件中,当您执行以下操作时:
set myvar="c:\my music & videos"
该变量myvar
与包含的引号一起存储。老实说,我觉得这很愚蠢。引号只是说明字符串的开始和结束位置,而不是作为值本身的一部分存储。
我怎样才能防止这种情况发生?
谢谢。
set "myvar=c:\my music & videos"
注意引号在 myvar 之前开始。其实就是这么简单。旁注: myvar 之后不能回显,除非它用引号括起来,因为 & 将被读取为命令分隔符,但它仍然可以作为路径工作。
http://ss64.com/nt/set.html在“变量名可以包含空格”下
这是正确的方法:
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.
)
长话短说,&
在批处理文件中使用包含嵌入空格和/或 s 的路径或文件名确实没有干净的方法。
使用脚本。
许多个月前(即大约 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)
这两者都没有解释变量将完全具有您正在寻找的数据。
strong text 但是,出于您的目的,只有引用的方法才能有效工作,因为您使用的是保留字符
因此,您将使用:
set "myvar=c:\my music & videos"
但是,即使变量 IS 正确设置为该字符串,当您 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>
尝试使用转义字符'^',例如
set myvar=c:\my music ^& videos
扩展 myvar 时要小心,因为 shell 可能不会将 & 视为文字。如果上述方法不起作用,请尝试在字符串中插入插入符号:
set myvar=c:\my music ^^^& videos
两种解决方案:
不要在路径名(目录或文件名)中使用对命令解释器来说特殊的空格或其他字符。如果您只使用字母、数字、下划线和连字符(以及在扩展名之前的一个句点来识别文件类型),您的脚本编写工作将变得无比简单。
多年来,我编写并收集了大量工具,包括一个重命名文件的 DOS 实用程序。(它开始只是从文件名中删除空格,但演变成可以替换文件名中的字符或字符串的东西,甚至是递归的。)如果有人感兴趣,我会让我长期被忽视的网站启动并运行并发布这个和其他。
也就是说,变量不仅仅用于保存路径名,所以......
正如其他人已经指出的那样,SET "myvar=c:\my music & videos"是此类变量值的正确解决方法。(是的,我说的是解决方法。我同意您最初倾向于仅引用值(“我的音乐和视频”)更直观,但正如他们所说,它就是这样。