for循环中的批处理子程序

时间:2016-03-30 12:01:50

标签: loops batch-file copy call

为什么这不起作用的任何想法?我试图在子例程中用%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并退出而不复制。程序只是不执行错误级别检查帮助!:

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

1 个答案:

答案 0 :(得分:3)

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

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是{{1 }} 在那里。因此,您还需要将批处理文件名称传递给子例程:

: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""
)