处理Windows批处理脚本中的引号
在Windowsbatch file中,执行以下操作时:
set myvar="c:\my music & videos"
variablesmyvar
与包含的引号myvar
存储。 老实说,我觉得很愚蠢。 引号只是告诉string开始和结束的位置,而不是存储为值本身的一部分。
我怎样才能防止这种情况发生?
谢谢。
set "myvar=c:\my music & videos"
注意引号在myvar之前开始。 其实很简单。 注意:除非用引号括起来,否则myvar不能被回显,因为&将被作为命令分隔符读取,但仍然可以作为path使用。
“variables名称可以包含空格”下的http://ss64.com/nt/set.html
这是做到这一点的正确方法:
set "myvar=c:\my music & videos"
引号将不会包含在variables值中。
这取决于你想如何使用variables。 如果您只想使用不带引号的variables值,则可以使用延迟扩展和stringreplace,也可以使用for
命令:
@echo OFF SETLOCAL enabledelayedexpansion set myvar="C:\my music & videos"
如andynormancx所述,由于string包含&
,因此需要引号。 或者你可以用^
来逃避它,但是我认为这些报价比较干净。
如果在stringreplace中使用延迟扩展,则会得到不带引号的variables的值:
@echo !myvar:"=! >>> C:\my music & videos
你也可以使用for
命令:
for /f "tokens=* delims=" %%P in (%myvar%) do ( @echo %%P ) >>> C:\my music & videos
但是,如果要在命令中使用该variables,则必须使用引用的值或将引号中的variables值括起来:
-
使用stringreplace和延迟扩展来使用不带引号的variables的值,但在命令中使用variables:
@echo OFF SETLOCAL enabledelayedexpansion set myvar="C:\my music & videos" md %myvar% @echo !myvar:"=! created.
-
使用
for
命令来使用不带引号的variables的值,但是在命令中使用variables时,必须用引号括起variables:@echo OFF set myvar="C:\my music & videos" for /f "tokens=* delims=" %%P in (%myvar%) do ( md "%%P" @echo %%P created. )
长话短说,在batch file中使用包含embedded空格和/或&
s的path或文件名真的没有干净的方法。
使用jscript。
许多天以前(即大约8年的时间)我正在开发一个大型C ++ / VB6项目,并且我有各种各样的批处理脚本来完成部分构build。
然后有人指给我Joeltesting ,我特别喜欢第二点,并着手将我所有的小构build脚本合并到一个构build脚本中。 。 。
这几乎让我心碎,让所有这些小脚本在不同的机器上一起工作,而且设置略有不同,你们的上帝是可怕的 – 特别是设置variables和parameter passing。 它非常脆弱,最轻微的事情会打破它,需要30分钟的调整才能重新开始。
最终 – 我可以固执己见 – 我把所有的东西都放进去了 ,大概一天之内用JavaScript重新编写了所有的代码 ,然后用CScript的命令提示符运行它。
我没有回头。 尽pipe现在是MSBuild和Cruise Control,但是如果我需要做一些甚至与批处理脚本稍有关系的事情,我也会使用jscript。
Windows命令解释器允许您在整个set命令周围使用引号(在从NT 4.0到Windows 2012 R2的每个版本的Windows NT中都有效)
你的脚本应该写成如下:
@echo OFF set "myvar=C:\my music & videos"
那么你可以根据需要在variables周围加引号。
使用CMD提示可能有时似乎很深奥,但命令解释程序在遵守它的内部逻辑方面performance得相当稳固,您只需要重新思考问题。
事实上,set命令并不要求你使用引号,但是你做variables赋值的方式和使用不引号的方法都会导致你的variables有更多的空格,这些空格很难在debugging脚本时注意。
例如下面的两个都是技术上有效的,但是你可以有尾随空格,所以这不是一个好习惯:
set myvar=some text set myvar="some text"
例如下面的两个都是在Windows Command解释器中设置variables的好方法,但是双引号方法是优越的:
set "myvar=Some text" (set myvar=Some value)
这两个都没有任何解释variables将有你正在寻找的数据。
强壮的文本但是,为了您的目的,只有引用的方法才能正常工作,因为您正在使用保留字符
因此,你会使用:
set myvar="c:\my music & videos"
但是,即使variablesIS被正确地设置为这个string,当你使用ECHO时,命令解释器将把&符号解释为关键字来指示另一个语句。
所以如果你想要从variables中回显string,CMD解释器仍然需要被告知它是一个文本string,或者如果你不想要引号显示你必须执行以下操作之一:
回应variables与行情:
Echo."%myvar%"
回应variables没有行情:
Echo.%myvar:&=^&% <nul SET /P="%myvar%"
在上述两种情况下,您可以使用不带引号的string进行回显。 下面的示例输出:
C:\Admin> Echo.%myvar:&=^&% C:\my music & videos C:\Admin> <nul SET /P="%myvar%" C:\my music & videos C:\Admin>
如果您正在设置的文本包含特定字符(包括&) ,则必须有引号。 如果你的文字不包括&那么你不会需要报价。
例如,如果文本只是“C:\我的音乐”,那么你可以这样做:
set myvar = c:\my music
但是,因为你的文字有&你需要报价。
编辑:
或者戴夫在回答中说,你可以用^^^来解决问题,但要小心这种方法,因为&并不是你唯一需要逃避的angular色。 在实践中,坚持引用而不是逃避所有问题字符要容易得多。
尝试使用转义字符'^',例如
set myvar=c:\my music ^& videos
当你展开myvar时,你会小心,因为shell可能不会把&作为一个文字。 如果上述不起作用,请尝试在string中插入一个脱字符:
set myvar=c:\my music ^^^& videos