处理Windows批处理脚本中的引号

时间:2009-02-11 08:57:55

标签: windows batch-file quotes scripting

在Windows批处理文件中,执行以下操作时:

  

set myvar="c:\my music & videos"

变量myvar与所包含的引号一起存储。老实说,我发现这非常愚蠢。引号只是告诉字符串的开始和结束位置,而不是作为值本身的一部分存储 我怎样才能防止这种情况发生?

感谢。

8 个答案:

答案 0 :(得分:59)

这是正确的方法:

set "myvar=c:\my music & videos"

引号不会包含在变量值中。

答案 1 :(得分:50)

set "myvar=c:\my music & videos"

注意引号在myvar之前开始。实际上就是这么简单。 旁注:myvar之后不能回复,除非它用引号括起来因为&将被读作命令分隔符,但它仍然可以作为路径。

“变量名称可以包含空格”下的

http://ss64.com/nt/set.html

答案 2 :(得分:35)

这取决于您希望如何使用变量。如果您只想使用不带引号的变量值,可以使用延迟扩展和字符串替换,或for命令:

@echo OFF
SETLOCAL enabledelayedexpansion

set myvar="C:\my music & videos"

as andynormancx指出,由于字符串包含&,因此需要引号。或者你可以使用^来逃避它,但我认为报价更清晰。

如果使用带字符串替换的延迟扩展,则获得不带引号的变量值:

@echo !myvar:"=!
>>> C:\my music & videos

您还可以使用for命令:

for /f "tokens=* delims=" %%P in (%myvar%) do (
    @echo %%P
)
>>> C:\my music & videos

但是,如果要在命令中使用变量,则必须使用带引号的值或将变量的值括在引号中:

  1. 使用字符串替换和延迟扩展来使用不带引号的变量值,但在命令中使用该变量:

    @echo OFF
    SETLOCAL enabledelayedexpansion
    
    set myvar="C:\my music & videos"
    md %myvar%
    @echo !myvar:"=! created.
    
  2. 使用for命令使用不带引号的变量值,但在命令中使用变量时,您必须用变量括起变量:

    @echo OFF
    set myvar="C:\my music & videos"
    
    for /f "tokens=* delims=" %%P in (%myvar%) do (
        md "%%P"
        @echo %%P created.
    )
    
  3. 长话短说,在批处理文件中使用包含嵌入空格和/或&的路径或文件名真的没有干净的方法。

答案 3 :(得分:6)

使用jscript。

很多以前(即大约8年的时间),我正在开发一个大型的C ++ / VB6项目,并且我有各种批处理脚本来完成部分构建。

然后有人指着我Joel Test,我特别迷恋第2点,并着手将我所有的小构建脚本整合到一个单独的构建脚本中。 。

它几乎打破了我的心脏,让所有那些小脚本在不同的机器上一起工作,设置略有不同,你知道这是可怕的 - 特别是设置变量和参数传递。它真的很脆弱,最轻微的东西会破坏它,需要30分钟的调整才能重新开始。

最终 - 我可能会很顽固 - 我在大约一天内把所有内容放进去 用JavaScript重新编写,从命令提示符下运行它与CScript。

我没有回头。虽然现在它是MSBuild和Cruise Control,如果我需要做一些甚至稍微涉及批处理脚本的东西,我使用jscript。

答案 4 :(得分:2)

Windows命令解释程序允许您使用整个set命令的引号(在从NT 4.0到Windows 2012 R2的每个版本的Windows NT中都有效)

您的脚本应该写成如下:

@echo OFF

set "myvar=C:\my music & videos"

然后你可以根据需要在变量周围加上引号。

使用CMD提示有时候看起来很神秘,但是命令解释器在遵循它的内部逻辑时实际上表现得非常稳固,你只需要重新思考。

实际上,set命令根本不要求你使用引号,但是你进行变量赋值的方式和使用无引号的方法都会导致变量周围有额外的空格。调试脚本时很难注意到。

e.g。以下两个在技术上都是有效的,但你可以有尾随空格,所以这不是一个好习惯:

set myvar=some text   
set myvar="some text" 

e.g。以下两个都是在Windows命令解释器中设置变量的好方法,但双引号方法更优越:

set "myvar=Some text"
(set myvar=Some value)

这两个都不会解释变量将具有您正在寻找的数据。

强文但是,出于您的目的,只有引用的方法才能有效运行,因为您使用的是保留字符

因此,您将使用:

set myvar="c:\my music & videos"

但是,即使变量IS正确设置为此字符串,当您对ECHO进行ECHO时,命令解释器会将&符号解释为关键字以指示另一个语句。

因此,如果你想从变量中回显字符串,CMD解释器仍然需要被告知它是一个文本字符串,或者如果你不希望引号显示你必须执行以下操作之一:< / p>

使用引号回显变量:

Echo."%myvar%"

回显变量WITHOUT Quotes:

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>

答案 5 :(得分:1)

如果您设置的文字包含某些字符,必须必须包含引号,包括&amp; 。如果您的文字不包含&amp; ,则您不需要引号。

例如,如果文字只是“c:\ my music”,那么你可以这样做:

set myvar = c:\my music

但是因为你的文字有&amp; ,所以你需要引号。

修改

或者正如Dave在他的回答中所说,你可以用 ^^^ 来逃避问题角色,但要注意这种方法,因为&amp; 不是你唯一的角色需要逃避。在实践中,坚持引号而不是逃避所有问题字符要容易得多。

答案 6 :(得分:1)

尝试使用转义字符'^',例如

set myvar=c:\my music ^& videos

扩展myvar时你会小心,因为shell可能不会对待&amp;作为文字。如果上述方法无效,请尝试在插入字符串中插入插入符号:

set myvar=c:\my music ^^^& videos

答案 7 :(得分:0)

两种解决方案:

  1. 不要在路径名(目录或文件名)中使用空格或其他对命令解释器来说是特殊的字符。如果您只使用字母、数字、下划线和连字符(以及用于标识文件类型的扩展名前的句点),您的脚本编写工作将变得无比简单。

    多年来,我编写并收集了大量工具,包括一个可以重命名文件的 DOS 实用程序。 (它开始只是从文件名中删除空格,但演变成可以替换文件名中的字符或字符串的东西,甚至是递归的。)如果有人感兴趣,我将启动并运行我长期被忽视的网站并发布此内容和其他。

    也就是说,变量不仅仅用于保存路径名,所以...

  2. 正如其他人已经指出的那样,SET "myvar=c:\my music & videos" 是这种变量值的正确解决方法。 (是的,我说的是变通方法。我同意您最初只引用价值(“我的音乐和视频”)的倾向要直观得多,但正如他们所说的那样。