batch-file - 批处理文件 - 如何将 FindStr 与百分比一起使用

标签 batch-file registry environment-variables findstr

我有一个包含以下 header 的批处理文件:

@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

如果 SOME_VAR 是一个现有的环境变量,这就是我得到的。如果我删除该变量,我将获得预期的成功。

这里发生了什么?我还需要逃避什么吗?如果变量存在,我怎样才能在第二个上成功找到?我只对执行文本搜索感兴趣,其中搜索到的文本包含 % 字符并且恰好与现有变量名称匹配。

顺便说一句,用于比较的源最终也将是一个变量,我已经在其中加载了从 Windows 注册表中读取的 PATH。所以最终,我正在搜索的字符串将变成 /C:"^.%%SOME_VAR%%;.*$"

我的 PATH 变量如下所示:

%SOME_VAR%;C:\Windows\system32...................etc

最佳答案

是的,还需要另一层转义,因为管道的每一侧都是通过 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!")
)

--输出--

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

关于batch-file - 批处理文件 - 如何将 FindStr 与百分比一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30518366/

相关文章:

batch-file - CD环境变量什么时候更新?

registry - 将值写入 Inno Setup 中存储在数组中的所有注册表项

.net - 已安装 VSTO x64 运行时但找不到

django - 如何使用不同的动态 DJANGO_SETTINGS_MODULE 环境变量在同一服务器中运行两个 Django 应用程序

windows - 执行批处理文件时出现 `The application failed to initialize properly`/3221225794 错误

windows - 如何在 Windows 批处理脚本中检查 URL 是否有效

c++ - 添加需要管理员才能启动的程序

java - 在类中读取命令行 gradle vars

bash - 如何在 Ubuntu 上设置运行环境?

batch-file - 如何批量输出不带扩展名的文件名?