for循环中的批处理子程序

Batch subroutine in for loop

知道为什么这行不通吗?我试图在子例程中将 %A% 替换为 %%f,但无论如何都行不通。

    SETLOCAL EnableDelayedExpansion
    for %%f in (*.bat) do (set A=%%f call :subroutine %%f)

    :subroutine
    findstr windowsisajoke %A%
    if %errorlevel%==0
    goto end
    copy %0 %A%
    :end

输出显示如下:

    FINDSTR: call cannot be opend.
    FINDSTR: :subroutine cannot be opend.
    test.bat:findstr windowsisajoke %A%
    FINDSTR: pause cannot be opend.

请告诉我这段代码有什么问题,我现在已经尝试了大约 3 天的时间来解决它:)。

一如既往,我们将不胜感激!谢谢!

这似乎适用于 %1 文件。该程序设置 %errorlevel%: 0 == 0 并在不复制的情况下退出。程序就是不执行errorlevel以下的命令 check Help!:

    for %%f in (*.bat) do (
      findstr windowsisajoke %1
       if not %errorlevel%==0 
      copy "%0" "%1"
     )

首先,您需要确保您的子例程不是 运行 在您的正常代码 运行s:

之后
rem code that calls the subroutine

goto :eof
:subroutine
rem ...

你需要在到达那个点之前退出。

然后实际上很清楚发生了什么:您将以下值分配给变量 %A%:

somefilename.bat call :subroutine %%f

当插入下面的 findstr 调用时,因为您的代码 运行 在那里,将导致以下结果:

findstr windowsisajoke somefilename.bat call :subroutine somefilename.bat

第一个参数之后的所有内容都将被解释为文件名。如您所见,这并不是您真正想要的。

您不需要在循环中设置任何变量,只需将文件名作为参数传递即可。此外,子例程参数的处理方式与批处理文件参数的处理方式相同:%1%2、...

这样,你的代码就变成了这样:

for %%f in (*.bat) do call :subroutine "%%f"
goto :eof

:subroutine
findstr windowsisajoke %1
if %errorlevel%==0 goto :eof
copy "%0" "%1"

我冒昧地修正了一些错误,这些错误会破坏文件名中的空格。也不需要在文件末尾有标签,因为 goto :eof 这样做,即使没有这样的标签。但是,仍然存在一个问题,因为您试图将当前批处理文件 (%0) 复制到当前循环中的批处理文件,这在子例程中无法工作,因为 %0:subroutine 在那里。因此,您还需要将批处理文件名传递给子例程:

for %%f in (*.bat) do call :subroutine "%%f" %0
goto :eof

:subroutine
findstr windowsisajoke %1
if %errorlevel%==0 goto :eof
copy "%2" "%1"

也不再需要延迟扩展,因为您从未设置变量。

现在,您也可以在没有子程序的情况下完成所有这些操作:

for %%f in (*.bat) do (
  findstr windowsisajoke "%%f"
  if not %errorlevel%==0 copy "%0" "%%f"
)

甚至:

for %%f in (*.bat) do (
  findstr windowsisajoke "%%f" || copy "%0" ""%%f""
)

如果你不喜欢输出,你可以重定向它:

for %%f in (*.bat) do (
  findstr windowsisajoke "%%f" || copy "%0" ""%%f""
) >nul 2>&1