I'm trying to output a checksum for six hundred tif files in a directory. I want each line to show the checksum followed by its respective file name.
For example:
b1039a6f0c4295916a82833f507f5e78 vol1_0001.tif
dd3fb454e8d4912934f7626baf105e36 vol1_0002.tif
etc.
Here is what I have tried:
for %%F in (vol1*.*) do certutil -hashfile "%%F" md5 | find /V "hash" >>temp.txt
for %%a in (vol1*.*) do set filename=%%~nxa
for /f "tokens=* delims=" %%i in (temp.txt) do set hash=%%i
@echo %hash% %filename% >>CheckSum.md5
The first part works fine, and I get a .txt
file of all the checksums I need. But the second part is not working.
All I get is the checksum, and file name pair, for the last file in the directory, repeated a bunch of times.
I have also tried this way on the recommendation of a colleague, but this didn't work either:
@echo off
Set "Folder=C:\Users\Me\desktop\MyFolder"
Set "OutPutFile=%~dp0HashList.md5"
Type nul>"%OutPutFile%"
SetLocal EnableDelayedExpansion
@for /f "delims=" %%a in ('Dir /S /B /A-D "%Folder%"') do (
@for /f "skip=1 delims=" %%H in ('CertUtil -hashfile "%%~a" md5 ^| find /V "hash"') do set "Hash=%%H"
echo %%a, !Hash: =!
echo %%a, !Hash: =! >>"%OutPutFile%"
)
I got a list of the file names, but each had the exact same checksum (for the last file in the directory).
This code solves your problem in the most efficient way:
@echo off
setlocal
set "Folder=C:\Users\Me\desktop\MyFolder"
set "OutPutFile=%~dp0HashList.md5"
(
for %%F in ("%Folder%\vol1*.*") do (
set "hash="
for /F "skip=1" %%a in ('certutil -hashfile "%%F" md5') do (
if not defined hash (
echo %%a %%F
set "hash=1"
)
)
)
) > "%OutPutFile%"
This approach include these efficiency features:
find.exe
) to locate the hash line of every file, but take it directly from the second output lineIf the number of files to process is large, like six hundred files, the difference in time from this method to other one that uses find
and append >>
redirection will be very noticeable...