在 BATCH 中使用 HASH SHA1 比较两个文件夹中的文件

Compare files from two folders using HASH SHA1 in BATCH

我有这个批处理代码,但它是错误的,我需要在屏幕上看到 folder2 中不在 folder1 中的文件的名称,将它们与您的 HASH SHA1 进行比较。临时文件位于同一目录中。 感谢您的评论

@echo off
cd folder1
FOR /F "Delims=" %%A in ('DIR /B/A-D *.*') DO (
    certUtil -hashfile "%%A" SHA1 | findstr /VI "HASH"| findstr /VI "certutil"
) >>folder2\output.tmp

cd folder2
FOR /F "Delims=" %%B in ('DIR /B/A-D *.* ^|Findstr /VEIL ".tmp"') DO (
    certUtil -hashfile "%%B" SHA1 | findstr /VI "HASH"| findstr /VI "certutil" >>output2.tmp
    FOR /F "Delims=" %%C in ('TYPE output2.tmp^|findstr /XLIV /G:output.tmp') DO (echo "%%B") 
)
  • certutil hash 没有其他行的冒号。
  • 只有散列的文件没有相应的文件就没有意义
  • 以下批次为两个文件夹创建哈希文件名对
  • 此外,如果文件夹 1 中存在,则检查文件夹 2 中的每个散列 - 如果不存在,则会将其回显到屏幕上。

@echo off
Set Dir1=A:\
Set Dir2=Q:\Test17\

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

样本运行:

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

样本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:\Test17\Get-EpubMetaInfo.ps1
aa37d47dc96380532c88559045b6c3fa080e2556 Q:\Test17\Get-MSebooks.ps1
ae29aeca5a433993ec854ddea6d8469516d2293c Q:\Test17\Handle-ZipFile.psm1
c10937240668c7c09dbac247b5cb0e30f027cfe6 Q:\Test17\SO_45490060.cmd
47c005b12889d32107b53bdbd16e94f029d330c4 Q:\Test17\SO_45491838.cmd
52b8e933411859e450fde3e8735658d9f52159b0 Q:\Test17\SO_45494397.cmd

这是另一个不使用临时文件的解决方案。相反,它创建了一种类似 f|filename.ext=hash 的关联数组。所有的哈希都存储为变量,变量序列可以用set "f|"枚举。基本上,这使得很容易获得与目录 1 中的文件名相关的哈希列表,然后使用此列表来比较目录 2。如果预期变量未定义,则目录 2 中的文件在目录 1 中不存在。如果它被定义,然后比较散列并取消定义。末尾定义的任何内容都表示目录 1 中存在文件,但目录 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.