Kumar Vikramjeet
Kumar Vikramjeet

Reputation: 263

How to do Binary comparison of files recursively within 2 folder paths using cmd?

I need to write a script for binary comparison of all files within 2 folders recursively. The 2 folders are installation folders and contain same files, but they are installation folders of different versions. I need to find which files (.dll, .lib, .exe) have changed with regard to previous versions.

I have tried using fc command

fc /b %1\* %2\* > result.txt 

But, it compares files only inside the stated folder. I need to recursively compare all files within all folders.

I thought this can be achieved by for loop.

For /r C:\test\%%f in (*) do @fc /b %%f C:\test\%2\%%~nxf > result.txt  

The problem here is %%~nxf which only gives the file name not the relative path.

I tried using forfiles command:

forfiles /s /p C:\test\%1 /m * /c "cmd /c @fc /b %1\@relpath %2\@relpath"

@relpath introduces .\ in the middle of the path, which is messing up my complete path. Any pointers on this one will be highly appreciated.

Please help!

Upvotes: 7

Views: 9266

Answers (3)

Kumar Vikramjeet
Kumar Vikramjeet

Reputation: 263

My final code :-

@echo off
set count=0
del /f result.txt
subst Y: %1
subst Z: %2
for /r Y: %%f in (*) do (fc /b "%%f" "Z:%%~pnxf" |  find "no diff" >nul
if ERRORLEVEL 1 echo "%1%%~pnxf is different" >> result.txt
set /a count+=1)

subst Y: /D
subst Z: /D


echo Total Files Compared = %count% 

One thing, I didn't get, this script is not checking all differences. Once a difference is found, it gets printed on the result page. This was the exact thing I wanted. I guess the find command takes line by line as input, and once the string is not found, it quits, though I'm not sure. It's a very common problem, still I wasn't able to find the solution on the net, that's why I'm posting it here.

Upvotes: 3

user2033427
user2033427

Reputation: 883

A workaround could be to use subst to associate the path with a drive letter, and compare both. For example:

subst Y: "C:\test 1"
subst Z: "C:\test 2"
for /r Y: %%f in (*) do fc /b "%%f" "Z:%%~pnxf"
subst Y: /d
subst Z: /d

Hope this helps

EDIT: Handle the fc command output (long):

setlocal enabledelayedexpansion
subst Y: /d
subst Z: /d
pause
subst Y: "C:\test 1"
subst Z: "C:\test 2"
for /r Y: %%f in (*) do (
  set diff=1&for /f "tokens=1,2,3,4 delims= " %%i in ('fc /b "%%f" "Z:%%~pnxf"') do (
    if "%%i"=="Comparing" (echo.) else (
      if "%%k"=="longer" (echo LONGER   : %%j) else (
        if "%%i"=="FC:" echo NO DIFF  : %%f
        if "%%l"=="" (if "!diff!"=="1" (
          echo DIFFERENT: %%f
          echo %%i %%j %%k
          set diff=2
        ))
      )
    )
  )
)
subst Y: /d
subst Z: /d

Upvotes: 3

mvp
mvp

Reputation: 116387

This is solution requires to use 3rd-party tool, but it is very efficient.

You will need to get md5deep - it is just 20KB executable.

Then, execute it against first directory like this:

md5deep -l -r dir1 > old.txt

Result is saved in old.txt and looks like this:

e7c3fcf5ad7583012379ec49e9a47b28  .\a\file1.bin
2ef76c2ecaefba21b395c6b0c6af7314  .\b\file2.bin
45e19bb4b38d529d6310946966f4df12  .\c\file3.bin
...

Then, run it in negative matching mode against second directory:

md5deep -l -r -X old.txt dir2

It will print checksum and names of all files in second directory which differ from original.

You can also run it in standard checksumming mode against second dir and compare the result yourself.

At any rate, I doubt that you can get away with just cmd: you will have to write something in more higher-level language, like C/C++/C#/whatever.

Upvotes: 8

Related Questions