Microsoft tool to compare 2 directories

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
falcios
Posts: 43
Joined: 02 Mar 2017 05:38

Microsoft tool to compare 2 directories

#1 Post by falcios » 13 May 2017 09:24

Is there a Microsoft tool that will compare 2 directories?

I'm looking to see if there are duplicate files and their locations. Single files on one drive only, etc.

Thanks in advance.

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Microsoft tool to compare 2 directories

#2 Post by penpen » 13 May 2017 11:19

Yes "windiff.exe", but i'm not sure where to download it from, i have to search (but actually i don't have time).

penpen

falcios
Posts: 43
Joined: 02 Mar 2017 05:38

Re: Microsoft tool to compare 2 directories

#3 Post by falcios » 13 May 2017 14:23

Thanks for the response. I already have windiff and it does compare directories if there are the same. I was looking for a utility to go through folders and subfolders and output list of the what one folder has or has not, if there are duplicates or a single file.

Thanks.

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Microsoft tool to compare 2 directories

#4 Post by penpen » 13 May 2017 18:12

falcios wrote:I was looking for a utility to go through folders and subfolders and output list of the what one folder has or has not, if there are duplicates or a single file.
Windiff should be capable of that:
Use the menuitems listed under "Options" (and "Expand") in the menubar to list the information you need ("Show Identical Files", "Show Left-Only Files", ...).

penpen

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Microsoft tool to compare 2 directories

#5 Post by Aacini » 13 May 2017 19:24

Something like this, perhaps?

Code: Select all

@echo off
setlocal EnableDelayedExpansion

if "%~2" neq "" goto begin
echo CompDirs.bat dir1 dir2
echo/
echo Compare files in both directories
goto :EOF

:begin

rem Populate first tree
pushd "%~1" 2>NUL || (echo First directory not found & goto :EOF)
for /R %%a in (*.*) do (
   set "name=%%~a"
   set "file1["!name:*%cd%\=!"]=1"
)

rem Populate second tree and report files in both trees
popd
cd "%~2" 2>NUL || (echo Second directory not found & goto :EOF)
echo Files in both directories:
echo/
for /R %%a in (*.*) do (
   set "name=%%~a"
   set "name=!name:*%cd%\=!"
   if defined file1["!name!"] (
      echo !name!
      set "file1["!name!"]="
   ) else (
      set "file2["!name!"]=1"
   )
)
echo/
echo/

echo Files in first directory only:
echo/
for /F "tokens=2 delims=[]" %%a in ('set file1[ 2^>NUL') do echo %%~a
echo/
echo/

echo Files in second directory only:
echo/
for /F "tokens=2 delims=[]" %%a in ('set file2[ 2^>NUL') do echo %%~a

Note that this is just a proof of concept, so several features may be added.

Antonio

falcios
Posts: 43
Joined: 02 Mar 2017 05:38

Re: Microsoft tool to compare 2 directories

#6 Post by falcios » 14 May 2017 12:06

Thanks Antonio for the script.

Can you tell me where do I specify the folders to compare? Can it prompt me to enter the folder names?

Thanks.

ShadowThief
Expert
Posts: 1166
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: Microsoft tool to compare 2 directories

#7 Post by ShadowThief » 14 May 2017 14:18

By default you would pass the two folders to the script as parameters, using quotation marks if you've got spaces in your folder names for some reason.

Code: Select all

compdirs.bat "C:\Users\John\Desktop\Some Folder\" "D:\backup\Some Other Folder\subfolder1\"

elzooilogico
Posts: 128
Joined: 23 May 2016 15:39
Location: Spain

Re: Microsoft tool to compare 2 directories

#8 Post by elzooilogico » 15 May 2017 03:36

Continuing the script from Antonio, you may add a folder chooser either with powershell or CScript.

CScript is faster, but IMHO powershell is easier to work with.


Code: Select all

@echo off
setlocal EnableDelayedExpansion

set "_folder1_=" & set "_folder2_="

if "%~1" neq "" set "_folder1_=%~1"
if "%~2" neq "" set "_folder2_=%~2"

echo CompDirs.bat dir1 dir2
echo/
echo Compare files in both directories

rem Folder chooser with Powershell (slow)
if not defined _folder1_ call :folderSelection "%_folder1_%", _folder1_, "Select first folder"
if not defined _folder2_ call :folderSelection "%_folder2_%", _folder2_, "Select second folder"
rem Folder chooser with CScript (fast)
rem if not defined _folder1_ call :folderSelectionFast _folder1_, "Select first folder"
rem if not defined _folder2_ call :folderSelectionFast _folder2_, "Select second folder"

echo first dir:  %_folder1_%
echo second dir: %_folder2_%
echo/
if not defined _folder1_ if not defined _folder2_ goto :eof

:begin

rem Populate first tree
pushd "%_folder1_%" 2>NUL || (echo First directory not found & goto :EOF)
for /R %%a in (*.*) do (
   set "name=%%~a"
   set "file1["!name:*%cd%\=!"]=1"
)

rem Populate second tree and report files in both trees
popd
cd "%_folder2_%" 2>NUL || (echo Second directory not found & goto :EOF)
echo Files in both directories:
echo/
for /R %%a in (*.*) do (
   set "name=%%~a"
   set "name=!name:*%cd%\=!"
   if defined file1["!name!"] (
      echo !name!
      set "file1["!name!"]="
   ) else (
      set "file2["!name!"]=1"
   )
)
echo/
echo/

echo Files only in %_folder1_%
echo/
for /F "tokens=2 delims=[]" %%a in ('set file1[ 2^>NUL') do echo %%~a
echo/
echo/

echo Files only in %_folder2_%
echo/
for /F "tokens=2 delims=[]" %%a in ('set file2[ 2^>NUL') do echo %%~a

exit/B


rem Powershell folder chooser
:folderSelection
SetLocal & set "folder=%~1"
set "dialog=powershell -sta "Add-Type -AssemblyName System.windows.forms^|Out-Null;$f=New-Object System.Windows.Forms.FolderBrowserDialog;$f.SelectedPath='%~1';$f.Description='%~3';$f.ShowNewFolderButton=$false;$f.ShowDialog();$f.SelectedPath""
for /F "delims=" %%I in ('%dialog%') do set "res=%%I"
EndLocal & (if "%res%" EQU "" (set "%2=%folder%") else (set "%2=%res%"))
exit/B 0

rem CScript folder chooser
:folderSelectionFast
SetLocal
set "texto=%~2"
set "_vbs_file_=%Temp%\browse.vbs"
>"%_vbs_file_%" (
  echo Set oWs = CreateObject("Shell.Application"^)
  echo Set oBF = oWs.Namespace(^&H10^&^)
  echo Set oFI = oBF.Self
  echo strPath = oFI.Path
  echo Set oWs = CreateObject("Shell.Application"^)
  echo Set oBF = oWs.BrowseForFolder (0, "%texto%", ^&H201^&, strPath^)
  echo if oBF Is Nothing Then Wscript.Quit
  echo Set oFI = oBF.Self
  echo oPath = oFI.Path
  echo Wscript.Echo oPath
)

if exist "%Temp%\browse.vbs" (set "_spawn_=%Temp%\browse.vbs") else (set "_spawn_=browse.vbs")
for /F "tokens=1 delims=" %%A in ('cscript //nologo "%_spawn_%"') do (set "folder=%%A")
if exist "%_spawn_%" del /F "%_spawn_%">NUL 2>NUL
EndLocal & set "%1=%folder%"
exit/B

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Microsoft tool to compare 2 directories

#9 Post by Aacini » 15 May 2017 10:56

elzooilogico wrote:Continuing the script from Antonio, you may add a folder chooser either with powershell or CScript.

CScript is faster, but IMHO powershell is easier to work with.

Code: Select all

snip


Well, IMHO JScript is much easier than PowerShell! The version below use the same WSH BrowseForFolder method, but it only requires two JScript lines instead of the several ones for VBS.

I also added to this version the detection of duplicate files in the same directory.

Code: Select all

@echo off
setlocal EnableDelayedExpansion

if "%~2" neq "" set "folder1=%~1" & set "folder2=%~2" & goto begin

 > folder.js echo var folder = (new ActiveXObject("Shell.Application")).BrowseForFolder(0, WScript.Arguments(0), 0x340, 0x05 );
>> folder.js echo WSH.Echo(folder ? folder.self.path : "");

for /F "delims=" %%a in ('cscript //nologo folder.js "Select first directory"') do set "folder1=%%a"
if not defined folder1 goto :EOF
for /F "delims=" %%a in ('cscript //nologo folder.js "Select second directory"') do set "folder2=%%a"
if not defined folder2 goto :EOF

:begin

rem Populate first tree
pushd "%folder1%" 2>NUL || (echo First directory not found & goto :EOF)
for /R %%a in (*.*) do (
   set "name=%%~a"
   set "tree1["!name:*%cd%\=!"]=1"
   if not defined file1["%%~NXa"] (
      set "file1["%%~NXa"]="%%~Pa""
   ) else (
      set "dup1["%%~NXa"]=1"
      set "file1["%%~NXa"]=!file1["%%~NXa"]! "%%~Pa""
   )
)


rem Populate second tree and report files in both trees
popd
cd "%folder2%" 2>NUL || (echo Second directory not found & goto :EOF)
echo Files in both directories:
echo/
for /R %%a in (*.*) do (
   set "name=%%~a"
   set "name=!name:*%cd%\=!"
   if defined tree1["!name!"] (
      echo !name!
      set "tree1["!name!"]="
   ) else (
      set "tree2["!name!"]=1"
   )
   if not defined file2["%%~NXa"] (
      set "file2["%%~NXa"]="%%~Pa""
   ) else (
      set "dup2["%%~NXa"]=1"
      set "file2["%%~NXa"]=!file1["%%~NXa"]! "%%~Pa""
   )
)
echo/
echo/

echo Files only in "%folder1%":
echo/
for /F "tokens=2 delims=[]" %%a in ('set tree1[ 2^>NUL') do echo %%~a
echo/
echo/

echo Files only in "%folder2%":
echo/
for /F "tokens=2 delims=[]" %%a in ('set tree2[ 2^>NUL') do echo %%~a
echo/
echo/

echo Duplicate files in "%folder1%":
echo/
for /F "tokens=2 delims=[]" %%a in ('set dup1[ 2^>NUL') do (
   echo %%a  file duplicate in folders:
   for %%b in (!file1[%%a]!) do echo     %%~b
)
echo/
echo/

echo Duplicate files in "%folder2%":
echo/
for /F "tokens=2 delims=[]" %%a in ('set dup2[ 2^>NUL') do (
   echo %%a  file duplicate in folders:
   for %%b in (!file2[%%a]!) do echo     %%~b
)

The default start folder for directory selection is "My Documents", that is specified by 0x05 value in fourth parameter of BrowseForFolder method. You may also use 0x11 for "All drives" or 0 for "Desktop"; further details at this site.

Antonio

jfl
Posts: 226
Joined: 26 Oct 2012 06:40
Location: Saint Hilaire du Touvet, France
Contact:

Re: Microsoft tool to compare 2 directories

#10 Post by jfl » 06 Jun 2017 09:52

Try my dirc.exe tool, available in SysTools.zip there:
https://github.com/JFLarvoire/SysToolsLib/releases
It's written in C, fast, supports any Unicode pathnames in any code page, long pathnames > 260 characters, junctions, symlinks, etc.
There are also many options for refining the comparison. Use option -? to display a help screen.

For example the -b option limits the output to files that are present in both directories:

Code: Select all

C:\JFL\Temp>dirc -b C:\Windows C:\Windows\System32

C:\Windows                                                 |                                        C:\Windows\System32

Boot                        <DIR>      2017-03-18 23:03:29 < Boot                        <DIR>      2017-03-19 04:47:47
en                          <DIR>      2017-03-29 17:24:03 > en                          <DIR>      2017-03-19 04:49:53
en-US                       <DIR>      2017-03-19 04:47:47 < en-US                       <DIR>      2017-05-14 21:29:58
IME                         <DIR>      2017-03-19 04:47:47 > IME                         <DIR>      2017-03-18 23:03:29
InputMethod                 <DIR>      2017-03-18 23:03:29 = InputMethod                 <DIR>      2017-03-18 23:03:29
Migration                   <DIR>      2017-03-18 23:03:29 < migration                   <DIR>      2017-03-30 02:39:01
Setup                       <DIR>      2017-03-30 02:42:15 > setup                       <DIR>      2017-03-19 04:47:48
Speech                      <DIR>      2017-03-18 23:03:29 = Speech                      <DIR>      2017-03-18 23:03:29
Speech_OneCore              <DIR>      2017-03-18 23:03:29 = Speech_OneCore              <DIR>      2017-03-18 23:03:29
Tasks                       <DIR>      2017-03-29 17:50:29 < Tasks                       <DIR>      2017-06-02 09:56:22
notepad.exe                     246784 2017-03-18 22:58:25 < notepad.exe                     246784 2017-03-18 22:58:29
write.exe                        11264 2017-03-18 22:58:25 = write.exe                        11264 2017-03-18 22:58:25

12 files or directories listed.

C:\JFL\Temp>

Post Reply