Windows用户定义的环境variables名称可以包含任何字符,除了=
。
特殊字符可以通过转义来包含。 一个简单的方法是简单地将整个SETexpression式括在引号中。 例如:
set "A weird & "complex" variable=My value" set A weird ^& "complex" variable=My value
上面的两个expression式都给出相同的结果 variables名称是A weird & "complex" variable
,值是My value
IF DEFINED结构用于testingvariables是否被定义。 行情不适用于此testing,名称(包括引号)中的特殊字符必须转义。
set "A&B=value" if defined A^&B echo This works if defined "A&B" echo This does not work
上面的逃脱testing工作得很好。 引用的testing不起作用
但是我怎样才能testing一个包含空格的variables是否存在?
set "AB=value" if defined A^ B echo this does not work!
似乎上面应该工作,但它不!
我正在寻找一个不涉及使用%AB%或!AB扩展variables的答案!
交流的问题(我爱这个语法基础问题)。
显然你知道如何检查延迟扩展和FOR参数的作品。
@echo off setlocal set "AAA BBB=value" set ""AAA BBB"=" set "AAA=" for %%a in ("AAA BBB") do if defined %%~a echo FOR: This works setlocal EnableDelayedExpansion set "varname=AAA BBB" if defined !varname! echo Delayed: This works if defined %varname% ( echo percent: Never comes here ) ELSE ( echo percent: Never comes here ? ) if defined AAA^ BBB ( echo escape1: Never comes here ) ELSE ( echo escape1: fails ) set AAA=Hello if defined AAA^ BBB ( echo escape2: It only test for AAA the BBB will be "removed" ) ELSE ( echo escape2: fails ) set "space= " if defined AAA!space!BBB echo inject space: This works if defined "AAA BBB" (echo Quote1: Never comes here ) ELSE ( echo Quote1: Fails ) set ""AAA BBB"=value" if defined "AAA BBB" echo Quote2: This works, it checks for "AAA BBB" with quotes
在我的opionion中,在escape2的例子中,解析器首先将这一行分割为标记:
<if> <defined> <AAA BBB> <echo ....
但是在if定义的执行时间重新扫描<AAA BBB>
令牌,所以它只获取AAA
。
你不能注入像AAA^^^ BBB
这样的第二个转义,因为这只能搜索名为AAA^
的变量
我看不到延迟/ FOR的解决方案,因为空间的逃脱总是失败。
编辑:它也可以用SET <varname>
来解决
ijprest的解决方案使用SET命令来测试变量,而不需要转义varname。
但是它也显示了在varname内部和末尾处的空间的interssting行为。
它似乎遵循这些规则:
SET varname
搜索以varname开头的所有变量,但首先删除varname的最后一个空格字符后面的所有字符,并删除所有前导空格。
所以你不能搜索以空格开头的变量(但是创建这样的varname也有点棘手)。
如果将变量名用引号括起来,那么同样的行为也是有效的,但是之后又存在一个规则。
如果至少有两个引号,请先删除最后一个引号后的所有字符。 使用引号内的文本,并使用“空格” – 规则。
样品。
set " abc def ghi" junk junk *** 1. removes the junk set " abc def ghi" *** 2. removes the quotes set abc def ghi *** 3. removes all after the last space, and the trailing spaces set abc def *** Search all variables beginning with abc def
我也喜欢这样的问题! 🙂
这是另一个可能的解决方案我想出了…使用SET本身来测试的存在,并使用ERRORLEVEL结果:
set "AB=foo" set AB >nul 2>nul&& echo 1. This works set "AB ">nul 2>nul&& echo 2. This works set "A weird & "complex" variable=foo" set A weird ^& "complex" variable >nul 2>nul&& echo 3. This works set "A weird & "complex" variable ">nul 2>nul&& echo 4. This works
请注意,这只适用于如果您的变量是唯一的,没有变量名称是另一个的前缀。 否则,您可能会误报误报,因为SET的默认行为是显示所有以您传递的参数开头的变量。 如果这可能是这样的话,你可以用findstr来筛选结果:
set "AB=" set "ABC=foo" set "AB ">nul 2>nul&& echo 5. Failed (false positive) set "AB "|findstr /B /L /C:"AB=" >nul||echo 6. This works (no false positive)
此外,变量名称后面的单个尾部空格似乎是必需的。 没有它,SET往往会错误地分析输入。 奇怪的是,如果你在“2> nul”和“&&”之间添加一个额外的空格,那么它会停止工作(除非你在“> nul”之前删除空格)。
另一种方法是重新分配给另一个变量(一个没有空格)并测试。 看这里:
rem Prepare ONLY variable 'ab' set "ab=123" echo [ab]=%ab% rem This will ouput: [ab] is defined set var=%ab% if defined var ( echo [ab] is defined ) else ( echo [ab] is not defined ) rem This will output: [cd] is not defined set var=%cd% if defined var ( echo [cd] is defined ) else ( echo [cd] is not defined )
我通过定义一个标志为真如果需要…
rem /* sample code */ set VAR_SET= if <some condition> set VAR_SET=TRUE&set VAR=this data has spaces rem /* test for VAR_SET using 'if defined' */ if defined VAR_SET ( rem /* do something with the other data in the variable %VAR% */ ) rem /* clear the flag */ set VAR_SET=