变量未在嵌套循环中正确设置



我有一个类似的问题,就像我在这里问的那样:嵌套循环

但是,我仍然没有解决似乎很小的"问题"。我已经实现了使用[FindStr][2]提到的解决方案,但是运行时比没有 FindStr 要长得多。所以我想保持该方法使用

IF not "!stringToTest:!searchValue!=!"=="!stringToTest!" echo Something

下面我发布一些可运行的代码。一开始,我只是用我想搜索的值设置我的数组,然后是一些我喜欢在其中搜索我预先设置的搜索值的示例"文本"。 我的策略:

  1. 用文本行循环浏览我的文件。对于每一行,测试每个搜索值的状态。
  2. 测试完所有搜索值后,转到下一行并检查每个搜索值是否存在。

所以我有两个嵌套的循环。在循环内的每一步,我都输出变量的当前值,这些变量似乎是正确的。我真的不知道我在这一行中的错误是什么,因为搜索功能无法正常工作:

IF not "!stringToTest:!searchValue!=!"=="!stringToTest!" echo Searchword is in Textline

这里可能只是一个小错误?我非常感谢本期的每一次提示。

@echo off
setlocal enabledelayedexpansion
set /a counter=0
set "searchValues=abc,xyz"
FOR %%G in (%searchValues%) do (
set arraySearchVal[!counter!]=%%G
set /a counter+=1
)
REM set arraySearchVal
set /a counter-=1
set "TextWhichNeedToBeSearched=tzu,abc,qsd"
FOR %%G in (%TextWhichNeedToBeSearched%) do (
set "stringToTest=%%G"
echo Textline:         !stringToTest!   
FOR /l %%I in (0,1,%counter%) do ( 
set "searchValue=!arraySearchVal[%%I]!"
echo Searchword:       !searchValue!
REM echo !stringToTest! found in Textline | findstr "!searchValue!"
IF not "!stringToTest:!searchValue!=!"=="!stringToTest!" echo Searchword is in Textline
)
echo/     
)
endlocal
pause

这属于K.I.S.S.方法论。通过使搜索参数成为数组变量,您的代码过于复杂。 你可以这样简化它。

@echo off
setlocal enabledelayedexpansion
set "searchValues=abc,xyz"
set "TextWhichNeedToBeSearched=tzu,abc,qsd"
FOR %%G in (%TextWhichNeedToBeSearched%) do (
set "stringToTest=%%G"
echo Textline:         !stringToTest!   
FOR %%I in (%searchValues%) do ( 
echo Searchword:       %%I
IF not "!stringToTest:%%I=!"=="!stringToTest!" echo Searchword is in Textline
)
echo/     
)
endlocal
pause

如果你真的想使用你的原始代码,你可以使用带有CALL命令的技巧来设置另一个变量,从而获得双变量扩展。然后将该变量与IF命令一起使用。

@echo off
setlocal enabledelayedexpansion
set /a counter=0
set "searchValues=abc,xyz"
FOR %%G in (%searchValues%) do (
set arraySearchVal[!counter!]=%%G
set /a counter+=1
)
REM set arraySearchVal
set /a counter-=1
set "TextWhichNeedToBeSearched=tzu,abc,qsd"
FOR %%G in (%TextWhichNeedToBeSearched%) do (
set "stringToTest=%%G"
echo Textline:         !stringToTest!   
FOR /l %%I in (0,1,%counter%) do ( 
set "searchValue=!arraySearchVal[%%I]!"
echo Searchword:       !searchValue!
REM echo !stringToTest! found in Textline | findstr "!searchValue!"
call set "temptest=%%stringToTest:!searchValue!=%%"
IF not "!temptest!"=="!stringToTest!" echo Searchword is in Textline
)
echo/     
)
endlocal
pause

在过多地讨论这个问题之前,如果不需要,为什么要创建一个计数器值列表? 为什么机器人循环第 1 组和第 2 组为 for L 循环提供特殊变量,因为您没有分配位置值。

还有一点,您要查看的文本字符串中是否存在的所有术语都是部分吗? 还是您总是要匹配完整的字符串? 如果要匹配完整的字符串,则只需要一个循环。

如果可能的话,IE 匹配的字符串是 Full 值,或者您希望在集合中找到的"整个单词"以查看。

EG

REM this sees if any of the arguments match the list of options using only one loop.
Set "_OptionsToMatch= -D -Delete -R -Remove "
FOR %%_ in (%*) DO (
Echo=%_OptionsToMatch% | FIND /I " %%~_ " )

假设由于某种原因,上述内容在这种情况下对您不起作用

好吧,让我们解决其他位,例如为什么要压缩一个有价值的数组?

@(echo off
setlocal enabledelayedexpansion
set "searchValues=abc,xyz"
set "TextWhichNeedToBeSearched=tzu,abc,qsd"
)
CALL :Main
( Endlocal
Pause
Exit /B
)
:Main
FOR %%G in (%TextWhichNeedToBeSearched%) do (
SET "stringToTest=%%G"
FOR %%g in (%searchValues%) do (
IF /I "!stringToTest:%%g!" NEQ "%%G" (
Echo The string "%%G" contains "%%g"
) ELSE (
Echo The string "%%G" does not contain "%%g"
)
)
)
Goto :EOF

如果需要所有这些,您可以修改上述内容,以使我想可以进行编号数组。

或者,如果您只想解决正在发生的事情:

延迟扩展不能完全替代调用命令或使用函数。

这是Inused只编写脚本而延迟扩展的原因之一,因为即使在复杂的工作中仍然需要调用函数来执行这些步骤作为循环的一部分。

这通常是在做很多有价值的人的时候,比如这里。

另一种有效的方法是创建循环来执行下一级的变量操作,哪个更快? 扬子晚报

哪个更简单 - 通常调用子函数。

哪个更容易遵循 - YMMV。

这是子函数方法:

@(echo off
setlocal enabledelayedexpansion
set /a "counter=0"
set "searchValues=abc,xyz"
set "TextWhichNeedToBeSearched=tzu,abc,qsd"
)
CALL :Main
( Endlocal
Pause
Exit /B
)
:Main
FOR %%G in (%searchValues%) do (
set /a "counter+=1"
set "arraySearchVal[!counter!]=%%G"
)

FOR %%G in (
%TextWhichNeedToBeSearched%
) do (
set "stringToTest=%%G"
echo Textline:         !stringToTest!   
FOR /l %%I in (1,1,%counter%) do ( 
Call set "searchValue=!arraySearchVal[%%I]!"
echo Searchword:       !searchValue!
CALL :Fn_Compare
If !_CmpResult! == 0 (
Echo=the string did not exist.
Echo=Even in your loop you can use this result now.
)  ELSE (
Echo=the string does exist.
Echo=Even in your loop you can use this result now.
)
)
echo/ 
)
Goto :EOF
:Fn_Compare
REM echo !stringToTest! found in Textline | findstr "!searchValue!"
IF /I "!stringToTest:%searchValue%=!" NEQ "!stringToTest!" (
echo Searchword is in Textline
Set "_CmpResult=1"
) ELSE (
Set "_CmpResult=0"
)
Goto :EOF

这不是你需要的全部吗?

@Echo Off
Set "TextWhichNeedToBeSearched=tzu,abc,qsd"
Set "SearchValues=abc,xyz"
Set "ResultString=Searchword is in Textline"
For %%# In (%SearchValues%)Do (
Echo Textline:         %TextWhichNeedToBeSearched%
Echo Searchword:       %%#
Echo("%TextWhichNeedToBeSearched%"|FindStr "<%%#>">NUL 2>&1&&(
Echo(%ResultString%)||Echo(%ResultString:is=is not%
Echo(
)
Pause

最新更新