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
知道为什么这行不通吗?我试图在子例程中将 %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