【问题标题】:Batch file - findstr command fails using multiple strings to search for批处理文件 - findstr 命令使用多个字符串搜索失败
【发布时间】:2020-07-07 19:54:23
【问题描述】:

此批处理文件循环使用逗号分隔符 (IP_List.txt) 的计算机 IP 地址和密码列表。然后运行命令以远程连接到每台计算机。我还有另一个 IP 列表,它们是例外,需要跳过,所以我有一个变量 (set str=) 列出了这些 IP,我正在使用 findstr 搜索它们:

@ECHO OFF
setlocal EnableDelayedExpansion
Pushd "%~dp0"
Set Log=LogFile.log
set str=172.16.66.1 172.16.66.2 172.16.66.3 172.16.66.4
FOR /F "tokens=1,2 delims=," %%i in (IP_List.txt) do call :process %%i %%j
(ECHO+ & ECHO --- END OF REPORT ---) >> %Log%
GOTO :EOF
:process
set IP=%1
set PW=%2
@ECHO %IP% | findstr "%str%" >nul
IF NOT ERRORLEVEL 1 (ECHO+ & ECHO %IP% & ECHO This IP address was skipped) >> %Log% & GOTO :EOF
@ECHO Processing %IP% >> %Log%

---- (remainder of batch file here) ----

findstr 的问题在于例外列表中有 172.16.66.2,findstr 错误地在我的整体列表中找到了与以下 IP 的匹配项:172.16.66.224、172.16.66.225、172.16.66.226 等。

在更改代码并将 IP 异常列表放入文本文件 (IP_Exceptions.txt) 后,我能够解决 findstr 问题,并且这个修改后的批处理文件可以正常工作:

@ECHO OFF
setlocal EnableDelayedExpansion
Pushd "%~dp0"
Set Log=LogFile.log
FOR /F "tokens=1,2 delims=," %%i in (IP_List.txt) do call :process %%i %%j
(ECHO+ & ECHO --- END OF REPORT ---) >> %Log%
GOTO :EOF
:process
set IP=%1
set PW=%2
::~~ Add a right bracket to the end of the IP address variable
SET IPstr=%IP%]%x%
set match=N
::~~ Loop through a list of IP address exceptions
::~~ (A left bracket has been added to the beginning of
::~~ each IP on the list in order to use it as a delimiter)
::~~ Add a right bracket to the end of the variable "%%j"
::~~ in order to look for a match with the findstr command
for /F "delims=[" %%i in (IP_Exceptions.txt) do (
 for /F "tokens=1" %%j in ("%%i") do (
  ECHO %%j] | findstr "%IPstr%" >nul
  IF not errorlevel 1 set match=Y
 )
)
IF %match% == Y (ECHO+ & ECHO %IP% & ECHO Skipped this machine) >> %Log% & GOTO :EOF
@ECHO Processing %IP% >> %Log%

:: ---- (remainder of batch file here) ----

在没有错误匹配的情况下让 findstr 部分正常工作的细节(向变量添加括号、使用分隔符嵌套 for 循环等)虽然有点笨拙。任何有关提高该部分效率的建议将不胜感激。

【问题讨论】:

  • 那么为什么不将/G 选项与FINDSTR 一起使用呢?
  • 有一个bug with multiple search stringsFINDSTR 命令。
  • .findstr 的一个特殊元字符,意思是任何字符,所以你应该添加/L 开关来强制搜索字符串…跨度>
  • @Squashman,这应该(希望)不相关,因为示例搜索字符串的长度相同;即使它们不是,您也可以添加/I 选项,除了防止上述错误之外,它不会在这里改变任何东西......
  • 我刚刚找到了根本原因,这与例外列表中的IP超过四个无关。问题是,完整例外列表中的 IP 之一是 172.16.66.2。发生的情况是 IP 的 172.16.66.225 和 172.16.66.226 最终被错误地跳过。我一直在尝试不同的 findstr 开关,但仍然没有弄清楚如何解决这个问题。

标签: windows batch-file command-line-arguments findstr


【解决方案1】:

修改后的批处理文件有效,但很笨拙:

@ECHO OFF
setlocal EnableDelayedExpansion
Pushd "%~dp0"
Set Log=LogFile.log
FOR /F "tokens=1,2 delims=," %%i in (IP_List.txt) do call :process %%i %%j
(ECHO+ & ECHO --- END OF REPORT ---) >> %Log%
GOTO :EOF
:process
set IP=%1
set PW=%2
::~~ Add a right bracket to the end of the IP address variable
SET IPstr=%IP%]%x%
set match=N
::~~ Loop through a list of IP address exceptions
::~~ (A left bracket has been added to the beginning of
::~~ each IP on the list in order to use it as a delimiter)
::~~ Add a right bracket to the end of the variable "%%j"
::~~ in order to look for a match with the findstr command
for /F "delims=[" %%i in (IP_Exceptions.txt) do (
 for /F "tokens=1" %%j in ("%%i") do (
  ECHO %%j] | findstr "%IPstr%" >nul
  IF not errorlevel 1 set match=Y
 )
)
IF %match% == Y (ECHO+ & ECHO %IP% & ECHO Skipped this machine) >> %Log% & GOTO :EOF
@ECHO Processing %IP% >> %Log%

:: ---- (remainder of batch file here) ----

【讨论】:

    【解决方案2】:

    您的子程序可能如下所示:

    ...
    :process
    echo/ %str% |findstr /LC:" %1 " >nul && (
      echo %1 skipped
      goto :eof
    )
    echo processing %1 with %2
    :: ---- (remainder of batch file here) ----
    

    请注意,我颠倒了“搜索”逻辑(以便更容易正确处理空格)
    我不是echo <sub>|findstr <whole>,而是切换到echo <whole> |findstr <sub>

    注意:echo/ %str% |findstr /LC:" %1 " 中的空格很重要(它们也会进行比较以避免误报)。

    /LC: 告诉findstr 搜索文字(将点视为点而不是通配符)并包括空格。

    【讨论】:

    • 抱歉有任何混淆,但问题与 findstr 将点视为点而不是通配符无关。在我最初的帖子之后,我不得不对其进行几次编辑,以明确问题是什么,以及我修改后的批处理文件是如何解决它的。问题是由于 IP 172.16.66.2 在例外列表中而导致 findstr 出现误报。这已经通过我的新批处理文件解决了,此时我只是在寻找比我想出的更优雅的解决方案。
    • 是的,我明白了。我的代码会处理那些误报(处理带有/L 的点仅仅是“奖励”)
    • 猜猜我进入了奖金回合。你的代码很好用,谢谢。非常聪明地在搜索字符串中使用空格来避免误报。关于“echo/”....不知道斜线到底是做什么的,我以前从未见过,在任何地方都找不到它的记录。而且我知道 /L 和 /C 是单独的 findstr 开关,但我不知道它们可以像那样组合。在任何地方都找不到记录。
    • You're welcome/ 就是 make echo more reliable。在这种情况下,它只是让额外的空间非常明显。既然您提到了它-我还没有在任何(官方)文档中看到findstr 开关行为。但现在我已经习惯了,我什至不去想它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-24
    • 1970-01-01
    • 2023-02-11
    • 1970-01-01
    • 1970-01-01
    • 2015-11-05
    相关资源
    最近更新 更多