【问题标题】:Batch: Redirecting FC output, parsing, and claim variables批处理:重定向 FC 输出、解析和声明变量
【发布时间】:2016-10-19 20:05:53
【问题描述】:

我正在尝试使用 FC 来比较文件,但想获取 FC 命令的输出,将其解析出来,并声明变量以将源文件复制到不匹配的远程文件上,基本上是同步的。

我的代码非常简单,因为 fc 可以满足我的所有需求:

 @echo off

set source=C:\source\
set remote=C:\remote\

fc /b %source%\*.* %remote%\*.*

文件不同时的 fc 输出示例:

00000000 47 55
00000001 44 48
00000002 55 61
FC: C:\source\test.txt longer than C:\remote\test.txt

最后一行是我想要的,我想用文件路径解析并使用它们来声明要在中使用的变量

xcopy %sourcefile% %remotefile%

这需要能够解析多个 fc 文件输出。

【问题讨论】:

  • 您知道如果比较的文件不同但大小相同,则不会有最后一行,所以您只想同步长度变化的文件吗?如果源文件比相应的远程文件短怎么办?最后一行将被反转(它总是说“长于”,没有“短于”)......
  • 还有其他可能的同步方式:xcopy 可用于仅复制较新的文件 (/D) 和已存在的文件 (/U),或仅复制具有存档属性集的文件(/M) (系统会在文件编辑后立即设置); robocopy 建立高级同步选项...
  • 感谢您的洞察力。我不知道如果源较短,FC 的输出会反转。 FC 还可以基于二进制、ASCII 和/或 Unicode 进行比较;但前提是它可以打开并阅读它。我将进一步研究 xcopy 和 robocopy,看看这些是否是可能的途径。非常感谢!

标签: batch-file file-comparison


【解决方案1】:

FC.EXE will set an ErrorLevel as follows:

-1 Invalid syntax (e.g. only one file passed) 
0 The files are identical.
1 The files are different.
2 Cannot find at least one of the files.

您的脚本可能是(带有一些调试 echos 和 copy 命令由 REM 注释)。

@echo off

set "source=C:\source"
set "remote=C:\remote"

for /F "delims=" %%G in ('dir /B "%source%\" /A:-D') do (
  >NUL 2>&1 FC /b "%source%\%%~G" "%remote%\%%~G"
  if errorlevel 1 (
    echo %%G files differ or remote does not exist
    REM copy /B /Y "%source%\%%~G" "%remote%\%%~G"
  ) else (
    echo %%G files match
  )
)

不过,ROBOCOPY.exe - Robust File and Folder Copy 提供了更高级的选项,包括递归到子文件夹。

如果你因为任何原因不能使用ROBOCOPY,那么上面的脚本修改如下:

@ECHO OFF
SETLOCAL EnableExtensions

set "sourceMain=C:\source"
set "remoteMain=C:\remote"

call :subFolder "%sourceMain%" "%remoteMain%" "%sourceMain%"

rem traverse source subfolder structure
for /F "delims=" %%g in ('dir /B /S "%source%\" /A:D 2^>NUL') do (
  call :subFolder "%sourceMain%" "%remoteMain%" "%%~g"
)
ENDLOCAL
goto :eof

:subFolder
    rem adapted original script 
set "sourceRoot=%~1"
set "remoteRoot=%~2"

set "source=%~3"
call set "remote=%%source:%sourceRoot%=%remoteRoot%%%"     compute target folder

ECHO *** comparing "%source%" vs. "%remote%" ***
rem next command creates target folder if it does not exists yet
MD "%remote%" 2>NUL

for /F "delims=" %%G in ('dir /B "%source%\" /A:-D 2^>NUL') do (
  >NUL 2>&1 FC /b "%source%\%%~G" "%remote%\%%~G"
  if errorlevel 1 (
    echo %%G files differ or remote does not exist
    REM copy /B /Y "%source%\%%~G" "%remote%\%%~G"
  ) else (
    echo %%G files match
  )
)
goto :eof

请注意,Variable Edit/Replace 的目标文件夹计算从%%g 循环体移动到:subFolder 子例程,原因很方便:无需激活delayed expansion
请注意,%%G 循环保持不变。

【讨论】:

    【解决方案2】:

    (代表 OP 发布解决方案).

    感谢 ashipflJosefZ,我发现 ROBOCOPY 正是我所需要的。 SS64.com 有一个非常适合我的示例;下面的代码及其 ROBOCOPY 页面的链接:

    @ECHO OFF
    SETLOCAL
    
    SET _source=\\FileServ1\e$\users
    
    SET _dest=\\FileServ2\e$\BackupUsers
    
    SET _what=/COPYALL /B /MIR
    :: /COPYALL :: COPY ALL file info
    :: /B :: copy files in Backup mode. 
    :: /MIR :: MIRror a directory tree 
    
    SET _options=/R:0 /W:0 /LOG:C:\batch\RoboLog.txt /NFL /NDL
    :: /R:n :: number of Retries
    :: /W:n :: Wait time between retries
    :: /LOG :: Output log file
    :: /NFL :: No file logging
    :: /NDL :: No dir logging
    
    ROBOCOPY %_source% %_dest% %_what% %_options%
    

    http://ss64.com/nt/robocopy.html

    【讨论】:

      猜你喜欢
      • 2016-12-28
      • 1970-01-01
      • 2010-09-12
      • 1970-01-01
      • 2012-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多