如何在批处理文件中使用if子句中的括号转义变量?

Pio*_*ost 24 windows command-line escaping batch-file

运行此批处理文件

@echo off
set a=some value with (parentheses) inside
if 1 == 1 (
    set PATH=%a%
)
Run Code Online (Sandbox Code Playgroud)

给出inside was unexpected at this time.错误.

如何转义a变量以避免此错误?

jeb*_*jeb 29

您可以使用两种不同的方式

使用set引号的扩展语法set "var=content"将var设置为内容,引用内容,因此特殊字符不成问题,并使用内容直到最后一个引号(没有引号本身)

@echo off
set a=some value with (parentheses) inside
if 1 == 1 (
    set "PATH=%a%"
)
Run Code Online (Sandbox Code Playgroud)

使用延迟扩展(如shf301的答案),但也将值传输到主范围.

@echo off
setlocal enabledelayedexpansion
set a=some value with (parentheses) inside
if 1 == 1 (
    set "localScope_PATH=!a!"
    rem now transfer it to the global scope
    FOR /F "delims=" %%A in ("!localScope_PATH!") DO (
       endlocal
       set "path=%%A"
    )
)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,扩展的set-syntax不是必需的,我只用它来避免行末端的隐藏空格.

编辑: 我可以将它与setlocal EnableDelayedExpansion结合使用!而不是%到懒惰评估变量的值?当我尝试时,我得到了)!这时出人意料.

你可以这样做,但这样做很有成效

@echo off
Setlocal EnableDelayedExpansion
set a=some value with (parentheses) inside
if 1 == 1 (
    set PATH=!a:^)=^^^)!
    set path
)
Run Code Online (Sandbox Code Playgroud)

那么你的路径包含脱字在前面)C:\programs (x86^)

要了解扩展的工作原理,您可以阅读SO:Windows命令解释器(CMD.EXE)如何解析脚本?

EDIT2:更多的问题与路径(包含引号),
根据这个问题的时候路径包含引号也可以用括号occour另一个问题.

样品
path="C:\Program Files (x86)";C:\Program Files (x86)\Skype

这是允许的,即使这里没有必要使用引号,但这会破坏扩展SET语法,因为现在set "newPath=%path%"扩展为

set "newPath="C:\Program Files (x86)";C:\Program Files (x86)\Skype"
Run Code Online (Sandbox Code Playgroud)

现在至少有一个括号不在引号内,并且能够破坏命令块.

但是你可以简单地从路径变量中删除所有引号,如上所述,这里不需要引号.

set "newPath=%path:"=%"
Run Code Online (Sandbox Code Playgroud)


小智 5

)%a%是这里的问题。您可以做一些替换来逃脱)

@echo off
set a=some value with (parentheses) inside
if 1 == 1 (
    set PATH=%a:)=^)%
)
Run Code Online (Sandbox Code Playgroud)