嵌套DOS For循环问题

Kon*_*gMD 1 loops dos function batch-file

我对此批处理文件的目标是快速找出用户安装了多少个防病毒应用程序.我计划通过使用两个for循环来做到这一点:

  • 外循环:遍历Program Files目录中的文件夹名称
  • 内部循环:遍历常见防病毒名称列表(AVList变量),查找与当前目录名称的匹配项,并将每个匹配项附加到AntiVirus变量.

话虽如此,这是我失败的代码.我得到的错误是""此时出乎意料..请注意,我目前在AVList变量的Program Files中有文件夹名称(用于测试目的).

::@echo off
::variables
set AntiVirus="Initial Value"
set AVList=(adobe ccleaner auslogics)

SETLOCAL EnableDelayedExpansion

echo Checking Program Files...

if "%Processor_Architecture%" == "AMD64" (
echo 64-bit OS
echo.
for /d %%f in ("%ProgramFiles(x86)%\*") do (
   echo "%%f"
   SET "folder=%%f"
   REM Begin loop to search substrings with words in AVList
   Call:SearchAV "%folder%"
   )
) 
else echo 32-bit OS

echo.
echo AntiVirus: %AntiVirus%
echo.

for /d %%g in ("%ProgramFiles%\*") do (
   echo "%%g"
   SET "folder=%%g"
   REM Begin loop to search substrings with words in AVList
   Call:SearchAV "%folder%"
   )
)

:SearchAV
for %%v in ("%AVList%") do (
  echo "%%v"
  SET "av=%%v"
  if /I NOT "!~1:av=!"=="!~1!" set AntiVirus="%AntiVirus%%av%"
 )
GOTO:EOF

echo.
echo.
echo %AntiVirus% found
echo.
echo Script created by Matthew Ammann, revised by Andriy M from StackOverflow

@pause
Run Code Online (Sandbox Code Playgroud)

这是重定向到日志文件的输出:

C:\AVFinder>set AntiVirus="Initial Value" 

C:\AVFinder>set AVList=(adobe ccleaner auslogics) 

C:\AVFinder>SETLOCAL EnableDelayedExpansion 

C:\AVFinder>echo Checking Program Files... 
Checking Program Files...

C:\AVFinder>if "AMD64" == "AMD64" (
echo 64-bit OS  
 echo. 
 for / %f in ("C:\Program Files (x86)\*") do (
echo "%f"  
 SET "folder=%f"  
 REM Begin loop to search substrings with words in AVList  
 Call:SearchAV "C:\Program Files (x86)\Adobe" 
) 
) 
64-bit OS


C:\AVFinder>(
echo "C:\Program Files (x86)\Adobe"  
 SET "folder=C:\Program Files (x86)\Adobe"  
 REM Begin loop to search substrings with words in AVList  
 Call:SearchAV "C:\Program Files (x86)\Adobe" 
) 
"C:\Program Files (x86)\Adobe"
"" was unexpected at this time.

C:\AVFinder>  if /I NOT "!~1:av=!"=="!~1!" set AntiVirus=""Initial Value""(adobe ccleaner auslogics)""
Run Code Online (Sandbox Code Playgroud)

我哪里错了?

更新:我终于找到了一些时间来解决这个问题.这是更新的代码:

::This script is licensed under the Creative Commons Attribution license (CC BY 3.0) 
::Simply mention the original author in the source code if you make a derivative work.

@echo off
::variables
set AntiVirus=
set AVList=(norton mcafee kaspersky symantec avg comodo avast avira webroot eTRUST)

SETLOCAL EnableDelayedExpansion

echo Checking Program Files...

if "%Processor_Architecture%" == "AMD64" (
echo 64-bit OS
echo.
for /d %%f in ("%ProgramFiles(x86)%\*") do (
   echo "%%f"
   SET "path=%%f"
   Call:SearchAV "!path!"
   )
) else echo 32-bit OS

for /d %%g in ("%ProgramFiles%\*") do (
   echo "%%g"
   SET "path=%%g"
   Call:SearchAV "!path!"
   )
)
goto :END

:SearchAV
FOR %%a in %AVLIST% do (
  set res="%~n1"
  set res=!res:%%a=!
  if NOT "%~n1" ==!res! (
        ECHO "%~n1"  contains %%a
        if [!AntiVirus!] == [] (
            set AntiVirus="%~n1"
        ) else (
            set AntiVirus=!AntiVirus!, "%~n1"
        )   
    )
)
goto :eof

:END
echo.
echo.
echo !AntiVirus! found
echo.
echo Script created by Matthew Ammann, revised by members of Stack Overflow
echo 

@pause
Run Code Online (Sandbox Code Playgroud)

PA.*_*PA. 5

我看到几个问题

1.-您拥有:searchAV例程的地方会阻止最终代码执行.因此,将例程移到BAT文件的底部; 并更换PAUSEGOTO :EOF.看到HELP CALL

2.-在循环中设置环境变量需要延迟扩展才能正确分配.延迟扩展需要!VAR!检查的符号.所以,%FOLDER%改为!FOLDER!.但是,无论如何你都不需要它,因为你可以直接使用循环变量%%g.见HELP SET.

3.-循环使用字符串列表中的所有项目FOR与使用您使用的语法的命令不兼容.见HELP FOR.

那么,看看这段摘录,了解如何纠正您的BAT文件......

@ECHO off
SETLOCAL enabledelayedexpansion
set AVLIST=(Windows Microsoft)
FOR /d %%a in ("%ProgramFiles%\*") do (
   CALL :searchAV "%%a"
   )
GOTO :eof

:searchAV
FOR %%a in %AVLIST% do (
  set res=%1
  set res=!res:%%a=!
  if NOT %1==!res! ECHO %1 contains %%a
 )
GOTO :eof
Run Code Online (Sandbox Code Playgroud)