Batch file 批处理文件-如何将FindStr与百分比一起使用
我有一个具有以下标题的批处理文件:Batch file 批处理文件-如何将FindStr与百分比一起使用,batch-file,registry,environment-variables,findstr,Batch File,Registry,Environment Variables,Findstr,我有一个具有以下标题的批处理文件: @Echo off SETLOCAL EnableDelayedExpansion EnableExtensions 在括在括号中的If语句中,我有以下代码: Echo SOME_VAR|FindStr /r /C:"^.*SOME.*$" Echo Error: !errorlevel! Echo %%SOME_VAR%%|FindStr /r /C:"^.*SOME.*$" Echo Error: !errorlevel! 这将打印: SOME_VAR
@Echo off
SETLOCAL EnableDelayedExpansion EnableExtensions
在括在括号中的If
语句中,我有以下代码:
Echo SOME_VAR|FindStr /r /C:"^.*SOME.*$"
Echo Error: !errorlevel!
Echo %%SOME_VAR%%|FindStr /r /C:"^.*SOME.*$"
Echo Error: !errorlevel!
这将打印:
SOME_VAR
Error: 0
Error: 1
如果某个_VAR是一个现有的环境变量,这就是我得到的。如果我删除变量,我将获得预期的成功
这里发生了什么?我需要逃避更多吗?如果变量存在,如何在第二个变量上成功查找?我只对文本搜索感兴趣,其中搜索的文本包含%
字符,并且恰好与现有变量名匹配
顺便说一下,用于比较的源最终也将是一个变量,我在其中加载了从Windows注册表读取的路径。因此,我搜索的字符串最终将变成/C:“^.%%SOME_VAR%%;.*$”
我的路径变量如下所示:
%SOME_VAR%;C:\Windows\system32...................etc
是的,需要另一层转义,因为管道的每一侧都是通过命令行上下文而不是批处理上下文通过
CMD/C
执行的。初始批处理解析器将%%SOME\u VAR%%
转换为%SOME\u VAR%
。然后,如果变量未定义,命令行解析器会保留%SOME_VAR%
。如果定义了变量,我们需要防止扩展。加倍百分比在命令行上下文中不起作用。解决方案是在百分比之间插入一个消失的插入符号,如%^SOME\u 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!")
)
--输出--
谢谢,这是一个非常清楚的解释,它的工作。。。但是,当它是一个我正在回响的变量时,我该怎么做呢?它的值是
%SOME\u VAR%代码>。我无法构建正在搜索的字符串并在其中添加插入符号。显然这是一个很好的答案,但我看不出在这里使用cmd/v:on的原因。为什么不直接使用echo%%text%%| findstr“%%search%%”
?看起来这都是关于带百分比的普通变量名。那么扩张的百分比也是safe@jeb-啊!你说的对。我不必要地把搜索复杂化了。但是左侧处理注册表路径值,并且它可能包含正常扩展时不安全的内容。@dbenham-是的,我在上面评论时没有在右侧使用/neededcmd/v:on
。我的最后一行是cmd/v:on/c Echo^^!文字^^ ^|FindStr/r/C:“^.*%SOME_VAR%%;.*$”>NUL
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