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).
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).
Share Improve this question edited Nov 16, 2024 at 0:21 Compo 38.8k5 gold badges31 silver badges46 bronze badges asked Nov 15, 2024 at 21:58 Laura LannanLaura Lannan 131 silver badge3 bronze badges2 Answers
Reset to default 2This 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:
- It does not open/seek EOF/write/close the result file to output every checksum line, but keeps it open for all output lines
- It does not use an external .exe program (like
find.exe
) to locate the hash line of every file, but take it directly from the second output line
If 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...
You're very close, but redirecting certutil
to find /v "hash"
will only return one line, which you then skip with the skip=1
. Also, use capital letters for for
loop variables, since certain lowercase letters get interpreted as variable modifiers instead.
@echo off
SetLocal EnableDelayedExpansion
set "Folder=C:\Users\Me\desktop\MyFolder"
set "output_file=%~dp0Hashlist.md5"
for /f "delims=" %%A in ('Dir /S /B /A-D "%Folder%"') do (
for /f "delims=" %%H in ('CertUtil -hashfile "%%~A" md5 ^| find /V "hash"') do set "Hash=%%H"
echo !Hash: =! %%A
>>"%output_file%" echo !Hash: =! %%A
)