Windows 如何批量处理两个FOR循环?

Windows 如何批量处理两个FOR循环?,windows,batch-file,for-loop,Windows,Batch File,For Loop,我的问题是两个FOR循环分别工作,但不希望一个接一个地工作 目标是: 第一个循环创建XML文件,只有在创建完成后,第二个循环才会启动并计算创建的XML文件的大小,并将其写入.txt文件 @echo off Setlocal EnableDelayedExpansion for /f %%a in ('dir /b /s C:\Users\NekhayenkoO\test\') do ( echo Verarbeite %%~na jhove -m PDF-hul -h xml

我的问题是两个FOR循环分别工作,但不希望一个接一个地工作

目标是:

第一个循环创建XML文件,只有在创建完成后,第二个循环才会启动并计算创建的XML文件的大小,并将其写入.txt文件

@echo off
Setlocal EnableDelayedExpansion

for /f %%a in ('dir /b /s C:\Users\NekhayenkoO\test\') do (
    echo Verarbeite %%~na
    jhove -m PDF-hul -h xml -o C:\Users\NekhayenkoO\outputxml\%%~na.xml %%a
)

for /f %%i in ('dir /b /s C:\Users\NekhayenkoO\outputxml\') do (
    echo %%~ni %%~zi >> C:\Users\NekhayenkoO\outputxml\size.txt
)

pause

启动外部应用程序时,需要使用带有
/WAIT
标志的
START
命令。 我相信会是这样的:

START /WAIT jhove -m PDF-hul -h xml -o C:\Users\NekhayenkoO\outputxml\%%~na.xml %%a

这将导致批处理文件暂停,并等待外部应用程序完成后再继续操作。

如果知道什么是
jhove
,这个问题很容易回答

因此,我在万维网上搜索了
jhove
,很快找到了主页,并从jhove的SourceForge项目页面下载

我这么做是为了发现
jhove
是一个Java应用程序,它可以在Linux上执行,也可以在Mac上执行,使用shell脚本
jhove
,在Windows上使用批处理文件
jhove.bat
,以方便用户使用

因此,Windows命令解释器在环境变量
PATH
中指定的当前目录和下一个目录中搜索与文件名模式
jhove.*
匹配的文件,该文件的扩展名列在环境变量
PATHEXT
中,因为
jhove.bat
未指定文件扩展名并且批处理文件中没有路径

但是,如果不使用命令CALL从批处理文件中执行批处理文件,则会导致当前批处理文件的脚本执行在另一个执行的批处理文件中继续,而不会返回到当前批处理文件

由于这个原因,Windows命令解释器在目录
C:\Users\NekhayenkoO\test
中找到的第一个文件中运行到
jhove.bat
,并且再也不会返回

通过使用存储在
C:\Temp
中的两个简单批处理文件,可以很容易地观察到这种行为

Test1.bat:

@echo off
cd /D "%~dp0"
for %%I in (*.bat) do Test2.bat "%%I"
echo %~n0: Leaving %~f0
@echo %~n0: Arguments are: %*
@echo %~n0: Leaving %~f0
@echo off
cd /D "%~dp0"
for %%I in (*.bat) do call Test2.bat "%%I"
echo Leaving %~f0
Test2.bat:

@echo off
cd /D "%~dp0"
for %%I in (*.bat) do Test2.bat "%%I"
echo %~n0: Leaving %~f0
@echo %~n0: Arguments are: %*
@echo %~n0: Leaving %~f0
@echo off
cd /D "%~dp0"
for %%I in (*.bat) do call Test2.bat "%%I"
echo Leaving %~f0
从命令提示符窗口
C:\Temp\Test1.bat运行时,输出为:

Test2:参数是:“Test1.bat”
测试2:离开C:\Temp\Test2.bat

Test2.bat
上继续处理
Test1.bat
,而不返回
Test1.bat

现在,通过在
do
之后插入命令CALL
Test1.bat修改为

Test1.bat:

@echo off
cd /D "%~dp0"
for %%I in (*.bat) do Test2.bat "%%I"
echo %~n0: Leaving %~f0
@echo %~n0: Arguments are: %*
@echo %~n0: Leaving %~f0
@echo off
cd /D "%~dp0"
for %%I in (*.bat) do call Test2.bat "%%I"
echo Leaving %~f0
现在,在命令提示符窗口中运行
Test1.bat
时的输出为:

Test2:参数是:“Test1.bat”
测试2:离开C:\Temp\Test2.bat
Test2:参数是:“Test2.bat”
测试2:离开C:\Temp\Test2.bat
Test1:离开C:\Temp\Test1.bat

批处理文件
Test1.bat
现在调用批处理文件
Test2.bat
,因此在两个批处理文件的目录中找到的所有*.bat文件上都会执行FOR循环

因此,解决方案是使用commandCALL,如下所示:

使用对环境变量
USERPROFILE
的引用,而不是
C:\Users\NekhayenkoO

如果目录中的任何文件包含空格字符或任何其他需要用双引号括起来的特殊字符,则所有文件名都用双引号括起来

添加最后一个
2>nul
,它通过命令DIR将错误消息输出重定向到处理STDERR,以禁止在设备nul上查找任何文件。重定向运算符
必须在此处转义,并在执行命令DIR时解释
^
,而不是在分析命令时放置错误的重定向运算符

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读为每个命令显示的所有帮助页面

  • 呼叫/?
  • cd/?
  • dir/?
  • echo/?
  • 获取/?

也请阅读微软的文章。

它不起作用。无法完成外部应用程序。它已经处理一个pdf文件10分钟了。我不熟悉jhove的工作原理,但如果它的处理过程从未真正退出,批处理文件将不会超出
开始
行。我能想到的唯一其他解决方案是插入足够大的暂停,例如
TIMEOUT 10
以等待10秒,但这在其他方面可能不可靠或不可靠。有些程序不尊重/wait选项。这个电话总能帮我解决这个问题。很好。我不知道
CALL
可以用于外部应用程序,我认为它只适用于内置命令和子例程。您应该添加
CALL
作为答案。
CALL jhove-m PDF hul-h xml-o C:\Users\NekhayenkoO\outputxml\%%~na.xml%%一个
@Squashman,其结果可能与我的答案相同。如果
jhove
从未退出,执行将不会继续。@Squashman我添加了调用,它以正确的方式工作。谢谢!!!!