循环的批处理文件仅在一台机器上执行

时间:2015-12-08 17:56:56

标签: windows batch-file scripting

我编写了以下.bat文件,它在我的Windows 2000机器上运行完美,但不能在我的Windows 7或Windows XP机器上运行。基本上它只是遍历当前目录并运行校验和程序,该程序返回校验和。程序的输出保存到文本文件中,然后格式化以删除输出文件的校验和。

@Echo Off

for /r %%f in (*.txt) do crc32sum.exe %%f >> all_checksums.txt

ren all_checksums.txt old.txt
findstr /v /e /c:"all_checksums.txt" old.txt > all_checksums.txt
del old.txt

当我在带有一堆文本文件和文件夹中的crc32sum.exe的Win2k PC上运行此文件时,它会输出该文件。在其他机器上,它输出一个空白文件。我打开Echo并只保留for循环行,发现执行crc32sum.exe的输出什么都没有。如果您手动运行crc32sum.exe文件,它输出校验和没问题。

关于如何解决此问题的任何想法?

编辑:以下是该软件的链接:http://www.di-mgt.com.au/src/digsum-1.0.1.zip

EDIT2:新开发,如果文件夹的路径中没有空格,即C:\ temp或C:\ inetpub \ ftproot或C:\ users \ admin \ Desktop \ temp,该文件似乎有效。有谁知道如何使用包含空格的路径来完成这项工作? %% ~f无法正常工作,说意外。

1 个答案:

答案 0 :(得分:0)

尝试使用适用于Windows XP SP3 x86的修改后的批处理代码:

@echo off
goto CheckOutput

rem Command DEL does not terminate with an exit code greater 0
rem if the deletion of a file failed. Therefore the output to
rem stderr must be evaluated to find out if deletion was
rem successful or (for a single file) the file existence is
rem checked once again. For details read on Stack Overflow
rem the answer http://stackoverflow.com/a/33403497/3074564

rem The deletion of the file was successful if file created
rem from output message has size 0 and therefore the temp
rem file can be deleted and calculation of the CRC32 sums
rem can be started.

:DeleteOutput
del /F "all_checksums.txt" >nul 2>"%TEMP%\DelErrorMessage.tmp"
for %%E in ("%TEMP%\DelErrorMessage.tmp") do set "FileSize=%%~zE"

if "%FileSize%" == "0" (
    set "FileSize="
    del "%TEMP%\DelErrorMessage.tmp"
    goto CalcCRC32
)

set "FileSize="
echo %~nx0: Failed to delete file %CD%\all_checksums.txt
echo.
type "%TEMP%\DelErrorMessage.tmp"
del "%TEMP%\DelErrorMessage.tmp"
echo.
echo Is this file opened in an application?
echo.
set "Retry=N"
set /P "Retry=Retry (N/Y)? "
if /I "%Retry%" == "Y" (
    set "Retry="
    cls
    goto CheckOutput
)
set "Retry="
goto :EOF

:CheckOutput
if exist "all_checksums.txt" goto DeleteOutput

:CalcCRC32
for /R %%F in (*.txt) do (
    if /I not "%%F" == "%CD%\all_checksums.txt" (
        crc32sum.exe "%%F" >>"all_checksums.txt"
    )
)

如果先前运行中已存在,则删除当前目录中的输出文件。添加额外代码以验证删除是否成功并通知用户删除失败,并允许用户在关闭应用程序中的文件后重试,如果这是删除失败的原因。

FOR 命令搜索当前目录中的选项/R 递归,以及扩展名为txt的文件的所有子目录。对于在当前目录或任何子目录中找到的任何文本文件,包含完整路径的每个找到的文件的名称始终没有双引号,保留在循环变量F中。

CRC32总和由当前目录中的32位控制台应用程序crc32sum计算,用于找到除当前目录中的输出文件all_checksums.txt之外的所有文本文件。这个小应用程序的输出被重定向到文件all_checksums.txt,并将单个输出行附加到此文件。

有必要将带有路径的文件名用双引号括起来,因为即使没有* .txt文件在其名称中包含空格字符或其中一个特殊字符&()[]{}^=;!'+,`~,文件的路径也可能包含空格或其中一个字符。

对于文件

C:\Temp\test 1.txt
C:\Temp\test 2.txt
C:\Temp\test_3.txt
C:\Temp\TEST\123-9.txt
C:\Temp\TEST\abc.txt
C:\Temp\TEST\hello.txt
C:\Temp\TEST\hellon.txt
C:\Temp\Test x\test4.txt
C:\Temp\Test x\test5.txt

批处理执行后文件C:\Temp\all_checksums.txt包含:

f44271ac *test 1.txt
624cbdf9 *test 2.txt
7ce469eb *test_3.txt
cbf43926 *123-9.txt
352441c2 *abc.txt
0d4a1185 *hello.txt
38e6c41a *hellon.txt
1b4289fa *test4.txt
f44271ac *test5.txt

要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

  • cls /?
  • del /?
  • echo /?
  • for /?
  • goto /?
  • if /?
  • rem /?
  • set /?
  • type /?

在运行for /?时输出的其中一个帮助页面通知%~I%~fI%~dI%~pI%~nI,{{ 1}},%~xI%~sI%~aI%~tI

在批处理文件%~zI中使用(小写)作为循环变量并使用f引用它是语法错误,因为命令处理器需要接下来的循环变量。 %%~f是正确的,但与%%~ff(不包含引号的字符串)相比,%%~fI(具有完整路径和扩展名的文件/文件夹的名称)可能与%%~I不同。 / p>

不建议使用(那些)小写字母作为循环变量。最好使用大写字母或字符#作为循环变量。循环变量以及那些修饰符区分大小写,而批处理文件中的其他几乎所有内容都不区分大小写。