Compare files from two folders using HASH SHA1 in BATCH

懵懂的女人 提交于 2019-12-06 04:39:28

Here's another solution that uses no temporary files. Instead, it creates a sort of associative array like f|filename.ext=hash. All the hashes are stored as variables, and the series of variables can be enumerated with set "f|". Basically, this makes it easy to get a list of hashes tied to filenames in directory 1, then use this list to compare directory 2. If an expected variable is undefined, then the file in directory 2 does not exist in directory 1. If it is defined, then compare the hashes and undefine it. Whatever is left defined at the end indicates a file exists in directory 1 but not in directory 2.

@echo off & setlocal

if "%~2"=="" goto usage

pushd "%~1" || goto usage
for /f "delims=" %%I in ('dir /b /a:-d') do (
    for /f %%x in ('certutil -hashfile "%%~I" ^| find /v ":"') do set "f|%%~nxI=%%~x"
)
popd

pushd "%~2" || goto usage
for /f "delims=" %%I in ('dir /b /a:-d') do (
    if not defined f^|%%~nxI (
        echo %%~nxI does not exist in %~nx1\
    ) else (
        for /f %%x in ('certutil -hashfile "%%~I" ^| find /v ":"') do (
            setlocal enabledelayedexpansion
            if not "%%~x"=="!f|%%~nxI!" (
                echo %%~nxI hash mismatch
            )
            endlocal
            set "f|%%~nxI="
        )
    )
)

for /f "tokens=2 delims=|=" %%I in ('cmd /c set "f|" 2^>NUL') do (
    echo %%I does not exist in %~nx2\
)

goto :EOF

:usage
echo Usage: %~nx0 dir1 dir2
echo compares files in dir1 with those in dir2.
  • certutil hash has no colon the other lines do.
  • a file with only hashes doesn't make sense without the corresponding file
  • the following batch creates hash filename pairs for both folders
  • additionally each hash from folder2 is checked if present in folder1 - if not it is echoed to the screen.

@echo off
Set Dir1=A:\
Set Dir2=Q:\Test\2017\08\03\

PushD "%Dir1%"
(FOR /F "Delims=" %%A in ('DIR /B/A-D *.*'
 ) DO For /f "delims=" %%B in (
 'certUtil -hashfile "%%A" SHA1 ^| findstr /V ":"'
 ) Do Echo %%B %%~fA
)> "%Dir2%\output1.tmp"
PopD

PushD "%Dir2%"
Type Nul >output2.tmp
FOR /F "Delims=" %%A in ('DIR /B/A-D *.* ^|Findstr /LIVE ".tmp"'
) DO For /f "delims=" %%B in ('certUtil -hashfile "%%A" SHA1 ^| findstr /V ":"') Do (
       >> output2.tmp Echo %%B %%~fA
       Findstr "%%B" output1.tmp >Nul 2>&1 || Echo Hash %%B not in "%Dir1%" File %%~fA 
     )
)
PopD

Sample run:

> Q:\Test\2017\08\03\SO_45494397.cmd
Hash fcfd29ab1ba8b64411d5ce461a35f07907862533 not in "A:\" File Q:\Test\2017\08\03\Get-EpubMetaInfo.ps1
Hash aa37d47dc96380532c88559045b6c3fa080e2556 not in "A:\" File Q:\Test\2017\08\03\Get-MSebooks.ps1
Hash ae29aeca5a433993ec854ddea6d8469516d2293c not in "A:\" File Q:\Test\2017\08\03\Handle-ZipFile.psm1
Hash 2d0d7fc7927f007b8aba4032d1c9fe86074ec8a1 not in "A:\" File Q:\Test\2017\08\03\SO_45494397.cmd

Sample output_.tmp

> Type output1.tmp
c10937240668c7c09dbac247b5cb0e30f027cfe6 A:\SO_45490060.cmd
47c005b12889d32107b53bdbd16e94f029d330c4 A:\SO_45491838.cmd
af6cccbeec7b80cbb37143316bd910bf6dcf622e A:\SO_45494397.cmd

> Type output2.tmp
fcfd29ab1ba8b64411d5ce461a35f07907862533 Q:\Test\2017\08\03\Get-EpubMetaInfo.ps1
aa37d47dc96380532c88559045b6c3fa080e2556 Q:\Test\2017\08\03\Get-MSebooks.ps1
ae29aeca5a433993ec854ddea6d8469516d2293c Q:\Test\2017\08\03\Handle-ZipFile.psm1
c10937240668c7c09dbac247b5cb0e30f027cfe6 Q:\Test\2017\08\03\SO_45490060.cmd
47c005b12889d32107b53bdbd16e94f029d330c4 Q:\Test\2017\08\03\SO_45491838.cmd
52b8e933411859e450fde3e8735658d9f52159b0 Q:\Test\2017\08\03\SO_45494397.cmd
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!