如果使用文件比较 (FC) 时 *.CMD/批处理脚本存在其他问题

问题描述 投票:0回答:1

我一直在开发一个快速的 *.CMD 文件,以将 5 个本地硬盘驱动器文件与 5 个网络文件(应该相同)与 UNC 文件夹位置进行比较。

我已经得到了我认为应该起作用的东西,但不断收到错误,“此时预期有其他结果。”

我的 IF / ELSE 是否有问题或搞砸了? 这让我摸不着头脑。 我通常会用 Python 做一些简单的事情,但会在几台没有安装 Python 的计算机上运行它。

@echo off
setlocal enabledelayedexpansion

:: List of file names to compare
set file1=TestFile1.txt
set file2=TestFile2.txt
set file3=TestFile3.txt
set file4=TestFile4.txt
set file5=TestFile5.txt

:: Local folder path
set localFolder=C:\localFolderLocation

:: UNC path
set uncFolder=\\uncFolderLocation

:: Function to compare files
:compareFiles
set file1Path=%localFolder%\%file1%
set file2Path=%localFolder%\%file2%
set file3Path=%localFolder%\%file3%
set file4Path=%localFolder%\%file4%
set file5Path=%localFolder%\%file5%

:: Loop through the files
for %%F in (%file1% %file2% %file3% %file4% %file5%) do (
  fc /b "%localFolder%\%%F" "%uncFolder%\%%F" >nul
  if !errorlevel! equ 0 (
    echo %%F matches (0)
  ) else (
    echo %%F is different (1)
  )
)
goto :EOF

:: Call the function
call :compareFiles

我尝试将 IF 行中的“equ”更改为 ==,但这没有效果。 这是启用延迟扩展的问题吗? 有什么建议吗? 有什么方法可以单步执行 BATCH 脚本来逐行执行它以查找原因吗? 我已经很多年没有使用 Batch 编写脚本了。

感谢您的帮助或建议!

if-statement batch-file
1个回答
0
投票

在以

(
开头的命令块内,下一个发现的
)
不在双引号参数字符串内,或使用
^
转义以解释为文字字符,则被解释为命令块的结尾。发布的批次代码中有:

echo %%F matches (0)

在这种情况下,右圆括号被解释为命令 IF 的真正分支命令块的结尾。

)
左边的下一个
else
被解释为命令 FOR 的命令块的结尾。因此,此时不需要命令
else
,因为它不属于 IF 条件。

退出代码评估为

fc
的工作代码从最低到最高:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem List of file names to compare
set "file1=TestFile1.txt"
set "file2=TestFile2.txt"
set "file3=TestFile3.txt"
set "file4=TestFile4.txt"
set "file5=TestFile5.txt"

rem Local folder path
set "localFolder=C:\localFolderLocation"

rem UNC path
set "uncFolder=\\uncFolderLocation"

rem Loop through the files
for %%G in ("%file1%" "%file2%" "%file3%" "%file4%" "%file5%") do (
    %SystemRoot%\System32\fc.exe /B "%localFolder%\%%~G" "%uncFolder%\%%~G" 1>nul 2>nul
    if not errorlevel 1 (
        echo %%G matches (0^)
    ) else if not errorlevel 2 (
        echo %%G is different (1^)
    ) else (
        if not exist "%localFolder%\%%~G" echo ERROR: Missing file: "%localFolder%\%%~G"
        if not exist "%uncFolder%\%%~G" echo ERROR: Missing file: "%uncFolder%\%%~G"
    )
)
endlocal

退出代码评估从最高到最低为

fc
的另一种解决方案:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem List of file names to compare
set "file1=TestFile1.txt"
set "file2=TestFile2.txt"
set "file3=TestFile3.txt"
set "file4=TestFile4.txt"
set "file5=TestFile5.txt"

rem Local folder path
set "localFolder=C:\localFolderLocation"

rem UNC path
set "uncFolder=\\uncFolderLocation"

rem Loop through the files
for %%G in ("%file1%" "%file2%" "%file3%" "%file4%" "%file5%") do (
    %SystemRoot%\System32\fc.exe /B "%localFolder%\%%~G" "%uncFolder%\%%~G" 1>nul 2>nul
    if errorlevel 2 (
        if not exist "%localFolder%\%%~G" echo ERROR: Missing file: "%localFolder%\%%~G"
        if not exist "%uncFolder%\%%~G" echo ERROR: Missing file: "%uncFolder%\%%~G"
    ) else if errorlevel 1 (
        echo %%G is different (1^)
    ) else echo %%G matches (0^)
)
endlocal

此代码适用于任何文件/文件夹名称,包括诸如

Development & Test 100% (!)
之类的名称,其中包含
&%!()
等字符,需要将整个文件名括在
"
中并禁用延迟变量扩展。如果在处理命令行时不必要地启用延迟变量扩展,则文件名中的感叹号将被解释为延迟扩展变量引用的开始/结束。

至少应该阅读这个答案问题章节:

  • 问题 1:文件/文件夹参数字符串未用引号引起来
  • 问题 2:单个命令使用命令块
  • 问题6:批处理文件依赖于外部定义的环境
  • 问题 7:使用字母 ADFNPSTXZadfnpstxz 作为循环变量

这些问题章节解释了对批处理文件代码应用的大部分修改。

::
是无效标签的开头。在通过
Windows 命令处理器
: 解析命令行时,除了当前执行带有标签的
GOTO
CALL 之外,零个或多个普通空格或水平制表符之后以 cmd.exe 开头的行将被忽略。以
(
开头并以匹配的
)
结尾的命令块内不支持标签。这意味着
::
(
内部也不支持
)
。在命令块内的零个或多个前导空格/制表符后使用以
:
开头的行会导致执行批处理文件时出现未定义的行为。它可能在测试中偶然起作用,但也可能现在或以后完全失败。因此,
::
不应用于评论。有注释命令REM用于注释。请注意,在识别命令
REM
之前,cmd.exe 首先使用 REM 解析整个命令行。因此,请小心注释中以命令
REM
开头的字符,例如 !%&)<>|。最好在评论中避免使用它们。

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

  • cmd /?
  • echo /?
  • endlocal /?
  • fc /?
  • for /?
  • if /?
  • rem /?
  • set /?
  • setlocal /?

其他推荐页面:

批处理文件中不应使用

%ERRORLEVEL%

!ERRORLEVEL!
。应始终使用命令 
IF 的帮助中描述的语法。对特定退出代码值(如命令或可执行文件的 5
)的评估可以通过以下方式完成:

if not errorlevel 6 if errorlevel 5 echo The dynamic variable ERRORLEVEL has value 5.
    
© www.soinside.com 2019 - 2024. All rights reserved.