是的,还需要另一层转义,因为管道的每一侧都是在命令行环境下通过
CMD /C
执行的,而不是批处理环境。初始批处理解析器将
%%SOME_VAR%%
转换为
%SOME_VAR%
。然后,如果变量未定义,命令行解析器将保留
%SOME_VAR%
不变。我们需要防止变量已定义时的扩展。在命令行环境中,加倍百分号无效。解决方案是在百分号之间插入一个消失的脱字符,如
%^SOME_VAR%
。脱字符被视为变量名的一部分,因此它可以防止变量扩展(除非您有一个名为
^SOME_VAR
的变量)。扩展失败后,脱字符会被正常的转义过程消耗。必须转义脱字符,以便批处理解析器将脱字符传递给
CMD /C
命令行环境。
最终批处理命令行如下:
Echo %%^^SOME_VAR%% | FindStr SOME_VAR
注意:我将FINDSTR命令简化为更简单但等效的搜索。
当您修改右侧的搜索以包括百分号时,您还需要插入转义符号。
针对评论中的问题更新:
以下代码演示了一些可能使用变量的方法:
@echo off
setlocal disableDelayedExpansion
:: Put both the text you want to search, as well as the search itself, in variables
set "text=%%SOME_VAR%%;C:\Windows\system32...................etc"
set "search=%%SOME_VAR%%"
echo text=%text%
echo search=%search%
echo(
echo(
echo Starting with delayed expansion disabled
echo -----------------------------------------
echo(
:: Use delayed expansion to safely expand any variable without worrying about content.
:: Both sides of the pipe are executed in a command line context with delayed expansion disabled.
:: You must use CMD /V:ON to enable delayed expansion within the pipe.
echo Test when SOME_VAR is undefined:
set "SOME_VAR="
if 1==1 (
cmd /v:on /c echo !text!|cmd /v:on /c findstr "!search!"
)
echo(
echo Test when SOME_VAR is defined:
set "SOME_VAR=DEFINED"
if 1==1 (
cmd /v:on /c echo !text!|cmd /v:on /c findstr "!search!"
)
echo(
setlocal enableDelayedExpansion
echo(
echo(
echo Now try with delayed expansion enabled
echo -----------------------------------------
echo(
:: Even though delayed expansion is enabled within the batch script, it is still disabled
:: within the pipe, so we still have to explicitly enable it via CMD /V:ON.
:: But now we must prevent expansion of the variables while in the batch context.
:: You have two options:
:: 1) Escape the !. The escape syntax changes depending on whether it is inside quotes or not:
echo Escape test:
if 1==1 (
cmd /v:on /c echo ^^!text^^!|cmd /v:on /c findstr "^!search^!"
)
echo(
:: 2) Enclose both sides of the pipe within parentheses (very weird, but it works)
echo Parentheses test:
if 1==1 (
(cmd /v:on /c echo !text!)|(cmd /v:on /c findstr "!search!")
)
--OUTPUT--
text=%SOME_VAR%;C:\Windows\system32...................etc
search=%SOME_VAR%
Starting with delayed expansion disabled
-----------------------------------------
Test when SOME_VAR is undefined:
%SOME_VAR%;C:\Windows\system32...................etc
Test when SOME_VAR is defined:
%SOME_VAR%;C:\Windows\system32...................etc
Now try with delayed expansion enabled
-----------------------------------------
Escape test:
%SOME_VAR%;C:\Windows\system32...................etc
Parentheses test:
%SOME_VAR%;C:\Windows\system32...................etc
%SOME_VAR%;
这样的值,我该怎么做呢?我无法构建我要搜索的字符串并在其中添加 carets。 - jeremfgecho %%text%% | findstr "%%search%%"
呢?因为似乎这只涉及到带有百分号的普通变量名。然后百分号扩展也是安全的。 - jebcmd /v:on
。我的最终行是cmd /v:on /c Echo ^^!text^^!|FindStr /r /C:"^.*%%SOME_VAR%%;.*$" >NUL
。 - jeremfg