Board logo

标题: [文件管理] 批处理根据MD5值查找重复文件 [打印本页]

作者: hfg1977    时间: 2010-8-10 17:46     标题: 批处理根据MD5值查找重复文件

新版本更新在 2楼:
更新内容:
1.可一次处理多个文件和文件夹;
2.可对单个或两个MD5列表文件处理;
3.可根据原有的MD5列表文件对多个文件和文件夹进行处理;
4.如上,适应性会更强些;
  1. 初始代码已清除
复制代码
md5.exe 程序简单介绍:
  1. 要获得帮助请输入:md5.exe -h ,其他方式诸如/?、/h、/help等无效
  2. md5 -h
  3. MD5  --  Calculate MD5 signature of file.  Call
  4.              with md5 [ options ] [file ...]
  5.          Options:
  6.               -csig   Check against sig, set exit status 0 = OK
  7.               -dtext  Compute signature of text argument
  8.               -l      Use lower case letters for hexadecimal digits
  9.               -n      Do not show file name after sum
  10.               -ofname Write output to fname (- = stdout)
  11.               -u      Print this message
  12.               -v      Print version information
  13. by John Walker  --  http://www.fourmilab.ch
  14. Version 2.0 (2003-04-15)
  15. This program is in the public domain.
  16. cn:
  17.                 - csig        核对文字签名,设置退出状态 0 = OK
  18.                         -cMD5 fname
  19.                         if %ERRORLEVEL%==0  OK
  20.                         if %ERRORLEVEL%==1  error
  21.                 - dtext        计算字符串参数的文字签名
  22.                         要验证 字符串的 MD5 值,就输入 md5.exe -d123456
  23.                         -d后面的字符不能带有空格,引号"会被忽略
  24.                 - l        的十六进制数字使用小写字母
  25.                 - n        不显示文件名
  26.                 - ofname        写输出到文件:fname
  27.                 - u        显示帮助信息
  28.                 - v        显示版本信息
  29. 该程序是在公共领域。
  30. md5 [drive[path]]
  31. [*.ext]
  32. md5<01.txt 等同于 md5 01.txt
  33. md5 -d^
  34. 系统就会提示 more? 输入字串就可以计算MD5了
  35. 结论:
  36. 123456                对应于:        md5<01.txt (01.txt只有一行"123456" 无回车换行)
  37.                         md5.exe -d123456
  38.                         echo.|set /p=123456|md5 -n
  39.                         set/p=123456^<nul|md5 -n
  40. set /p=123456<nul|md5 -n
  41. e10adc3949ba59abbe56e057f20f883e
  42. 123456空格        对应于:        md5<01.txt (01.txt只有一行"123456 " 有一个空格)
  43.                         set /p=123456<nul|md5 -n
  44. 7e8feb2276322ecddd4423b649dfd4d9
  45. 123456回车 对应于: echo 123456| md5.exe
  46. 41933e60e9c19b866b3d68864727afe7
  47. 123456空格回车 对应于: echo 123456 | md5.exe
  48. d170064a1951ad13095734a657c5a30f
复制代码
MD5文件下载: http://bbs.bathome.net/thread-2142-1-1.html
findDupFile.bat 这个是最老版本,不要下了:
作者: hfg1977    时间: 2010-9-24 02:06

  1. @goto start
  2. :help
  3. @echo.===== Ver: 1.1 =========================== 发布日期: 2010-09-24 =======
  4. @echo. BAT_NAME: findDupFile.bat
  5. @echo. 返回值: %ret_filename%
  6. @echo. 作用  : 根据MD5值查找重复文件
  7. @echo. 调用: ①findDupFile.bat [Path [EXT]] [file]
  8. @echo. ②findDupFile.bat [Path [EXT]] [file] [MD5_file1]
  9. @echo. ③findDupFile.bat [MD5_file1] [MD5_file2]
  10. @echo. [Path]: 文件夹路径 (可以是多个)
  11. @echo. [file]: 文件 (可以是多个)
  12. @echo. [EXT] : 文件后缀 如:"*.jpg *.bmp",带空格的必须用引号括起来
  13. @echo. [MD5_file] : MD5文件,形如"*_MD5.txt",带空格的必须用引号括起来
  14. @echo.====================== Copyright@ by hf-g ========= [彭城] ============
  15. ping /n 4 127.1>nul
  16. goto:end
  17. :start ============================================================
  18. @echo off&setlocal
  19. path=%path%;%~d0\DOS\command\第三方命令行程序
  20. set "ret_filename=%~dp0.\ret_List.txt"
  21. if /i "%~1"=="" goto help
  22. if /i "%~1"=="-?" goto help
  23. set "ext="&set "pathname="&set "Dir_name="&set "MD5_file1="&set "MD5_file2="&set "p_str="
  24. set /a exit_BL=0,D_count=0,f_count=0
  25. call:get_P %*
  26. if "%exit_BL%"=="1" goto end
  27. ::设置临时文件
  28. set "tmpfname=%pathname_0:~-2%"
  29. if "%tmpfname%"==":\" (
  30. set "Dir_name=drive_%pathname_0:~0,1%"
  31. call echo 驱动器名: %%Dir_name%%
  32. ) else (
  33. if "%pathname_0:~-1%"=="\" (
  34. call call:extpath "%%pathname_0:~0,-1%%"
  35. call echo 文件夹名: %%Dir_name%%
  36. ) else (
  37. if exist "%~1\" (
  38. set "Dir_name=%~nx1"
  39. call echo 文件夹名: %%Dir_name%%
  40. )
  41. )
  42. )
  43. if %f_count% GTR 0 set "Dir_name=list"
  44. if %D_count% GTR 1 set "Dir_name=list"
  45. set "tmpfname=%~dp0.\%Dir_name%_MD5.txt"
  46. cd.>"%ret_filename%"
  47. echo 生成MD5文件:    %tmpfname%
  48. echo 相同文件列表:    %ret_filename%
  49. echo 删除重复文件BAT: del_list.bat
  50. ::========================MAIN============================
  51. ::生成MD5文件,可一次处理多个文件夹和文件,只在批处理所在文件夹生成1个MD5文件.
  52. ::set "ext=*.jpg *.bmp"
  53. set/a D_count-=1,f_count-=1
  54. if not "%pathname_0%"=="" (
  55. cd.>"%tmpfname%"
  56. for /l %%i in (0,1,%D_count%) do (
  57. call pushd "%%pathname_%%i%%"
  58. (for /f "tokens=* delims=" %%i in ('dir /a-d/b/s %ext%') do (md5 "%%i"))>>"%tmpfname%"
  59. popd
  60. ))
  61. if not "%file_0%"=="" (
  62. if "%pathname_0%"=="" cd.>"%tmpfname%"
  63. for /l %%i in (0,1,%f_count%) do (call md5 "%%file_%%i%%")>>"%tmpfname%"
  64. )
  65. ::处理MD5文件━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  66. cd.>"%~dp0.\del_list.bat"
  67. if "%MD5_file1%"=="" (
  68. rem =========查找上面"生成MD5文件"中相同的文件,删除重复的====
  69. call:MD5_1file "%tmpfname%"
  70. ) else (
  71. if "%MD5_file2%"=="" (
  72. if not exist "%tmpfname%" (
  73. rem =========查找原有的唯一MD5列表文件中相同的文件,删除重复的====
  74. call:MD5_1file "%MD5_file1%"
  75. ) else (
  76. rem =========查找上面"生成MD5文件"与原有MD5文件中相同的文件,删除重复的====
  77. call:MD5_2file "%MD5_file1%" "%tmpfname%"
  78. )
  79. ) else (
  80. rem =========查找原有MD5_file1与原有MD5_file2文件中相同的文件,删除重复的====
  81. call:MD5_2file "%MD5_file1%" "%MD5_file2%"
  82. )
  83. )
  84. :end ==============================================================
  85. ::if exist "%tmpfname%" del "%tmpfname%" "%~dp0.\del_list.bat"
  86. exit /b
  87. ::=========查找MD5列表文件中相同的文件,删除重复的====
  88. :MD5_1file MD5_file
  89. for /f "tokens=1* delims= " %%a in ('type "%~1"') do (
  90. set/p =-<nul
  91. if defined _MD5_%%a (
  92. set/p =\<nul
  93. echo @del /f/q "%%b">>"%~dp0.\del_list.bat"
  94. set/p =^|<nul
  95. if not defined _write_%%a (findstr "^%%a" "%~1">>"%ret_filename%"&echo.>>"%ret_filename%"&set "_write_%%a=1")
  96. ) else (
  97. set "_MD5_%%a=1"
  98. )
  99. set/p =/<nul
  100. )
  101. goto:eof
  102. ::=========查找MD5_file1中与MD5_file2相同的文件,删除MD5_file2中重复的====
  103. :MD5_2file MD5_file1 MD5_file2
  104. (echo MD5_file1=%~1&echo MD5_file2=%~2)>con
  105. (echo MD5_file1=%~1&echo MD5_file2=%~2&echo.)>>"%ret_filename%"
  106. for /f "tokens=1* delims= " %%a in ('type "%~1"') do (set "_MD5_%%a=%%b")
  107. for /f "tokens=1* delims= " %%a in ('type "%~2"') do (
  108. set/p =-<nul
  109. if defined _MD5_%%a (
  110. set/p =\<nul
  111. echo @del /f/q "%%b">>"%~dp0.\del_list.bat"
  112. set/p =^|<nul
  113. (set _MD5_%%a&echo      %%a %%b&echo.)>>"%ret_filename%"
  114. set/p =/<nul
  115. )
  116. )
  117. goto:eof
  118. ::====================================================
  119. :extpath
  120. set "Dir_name=%~nx1"
  121. goto:eof
  122. ::========================参数设置与获得============================
  123. :get_p
  124. ::判断%1是_MD5.txt还是文件夹或其他文件或文件后缀
  125. if "%~1"=="" goto:eof
  126. set "p_str=%~1"
  127. if exist "%p_str%" (
  128. if "%p_str:~-8%"=="_MD5.txt" (
  129. if "%MD5_file1%"=="" (
  130. set "MD5_file1=%p_str%"&shift /1&goto get_p
  131. ) else (
  132. set "MD5_file2=%p_str%"&shift /1&goto get_p
  133. )
  134. )
  135. if exist "%p_str%.\" (
  136. call set "pathname_%%D_count%%=%p_str%"&set /a D_count+=1&shift /1&goto get_p
  137. )
  138. call set "file_%%f_count%%=%p_str%"&set /a f_count+=1&shift /1&goto get_p
  139. ) else (
  140. if "%ext%"=="" (
  141. if "%p_str:~0,2%"=="*." (
  142. set "ext=%p_str%"&shift /1&goto get_p
  143. )
  144. )
  145. echo %p_str% 不是一个正确的文件夹路径或文件^!&set /a exit_BL=1&shift /1&goto end
  146. )
  147. @echo off
  148. :get_p_end
  149. goto:eof
复制代码
链接: https://pan.baidu.com/s/12tmDkBEy0n-xWmbVNUpcbw?pwd=qix3
作者: hfg1977    时间: 2010-10-28 04:10

例子:
例子1: 查询 "G:\DOS\源码\29单身宿舍人员统计\" 文件夹中的重复文件,
把该文件夹拖到批处理上, 将生成如下3个文件:
①目标文件夹下所有文件的MD5列表文件: 源文件夹名_MD5.txt
②MD5重复的文件列表:                                  ret_List.txt
③构建好的删除多余重复文件的bat文件:    del_list.bat
29单身宿舍人员统计_MD5.txt         内容:
D41D8CD98F00B204E9800998ECF8427E  G:\DOS\源码\29单身宿舍人员统计\!234.txt
7D9FC79D6A8A320B3DC7B01FB90C79A5  G:\DOS\源码\29单身宿舍人员统计\29单身宿舍人员统计.bat
6FBCD072CBD00807F17DACFDCFACF8A9  G:\DOS\源码\29单身宿舍人员统计\29单身宿舍人员统计.exe
FA5ABD1410C43B23A52FD4EF28BBAFBE  G:\DOS\源码\29单身宿舍人员统计\AllPeople.txt
09A7E7205F0ED587242CA8AFD5552D9E  G:\DOS\源码\29单身宿舍人员统计\AllPeople1.txt
45F694C0558CB0255EDA33614597745E  G:\DOS\源码\29单身宿舍人员统计\filelist.txt
966A5E501EDD8CD23CA632773048BA26  G:\DOS\源码\29单身宿舍人员统计\Form1.frm
7331124867F742C3F1DBB39DDECF1396  G:\DOS\源码\29单身宿舍人员统计\MSSCCPRJ.SCC
C734E30DABB5901341E5F499D2448340  G:\DOS\源码\29单身宿舍人员统计\rar打包.bat
6DAAEF9B830CD36A93D0B7198B1014DC  G:\DOS\源码\29单身宿舍人员统计\sortfile.bat
CAA41244FB91DC85968C845F42AC240B  G:\DOS\源码\29单身宿舍人员统计\名字常用字.txt
D41D8CD98F00B204E9800998ECF8427E  G:\DOS\源码\29单身宿舍人员统计\复件 !234.txt
6FBCD072CBD00807F17DACFDCFACF8A9  G:\DOS\源码\29单身宿舍人员统计\复件 29单身宿舍人员统计.exe
1E973166964A66CA79A0E07FDFA01122  G:\DOS\源码\29单身宿舍人员统计\工程1.vbp
97B09906C471FA387B2862973DA9BA2E  G:\DOS\源码\29单身宿舍人员统计\工程1.vbw
BA905050B73B10F90D48EA1674BABC59  G:\DOS\源码\29单身宿舍人员统计\查询女职工.txt
77D2695EA3D4164FCBC680061CF57E14  G:\DOS\源码\29单身宿舍人员统计\百家姓.txt
083C860A2F4149972ADD011BC3D48280  G:\DOS\源码\29单身宿舍人员统计\随机姓名生成.bat
4536A3B26AD38A56D43ECE0D1929682F  G:\DOS\源码\29单身宿舍人员统计\photo\320323198003097032.JPG
82AA1106DD26203867CF957B5048642B  G:\DOS\源码\29单身宿舍人员统计\photo\NOIMAGE.jpg
               
ret_List.txt        内容:
D41D8CD98F00B204E9800998ECF8427E  G:\DOS\源码\29单身宿舍人员统计\!234.txt
D41D8CD98F00B204E9800998ECF8427E  G:\DOS\源码\29单身宿舍人员统计\复件 !234.txt

6FBCD072CBD00807F17DACFDCFACF8A9  G:\DOS\源码\29单身宿舍人员统计\29单身宿舍人员统计.exe
6FBCD072CBD00807F17DACFDCFACF8A9  G:\DOS\源码\29单身宿舍人员统计\复件 29单身宿舍人员统计.exe
   
del_list.bat   内容:

@del /f/q "G:\DOS\源码\29单身宿舍人员统计\复件 !234.txt"
@del /f/q "G:\DOS\源码\29单身宿舍人员统计\复件 29单身宿舍人员统计.exe"

作者: gie    时间: 2011-10-11 12:56

回复 3# hfg1977


    你好,能不能根据“不同md5” 但“相同文件名”进行分类呢,把它们移动到一个文件夹内,因为有的文件版本不同,想要把它们都放到一个文件夹内,但是Windows还不允许一个文件夹内有重名文件,所以不知道能不能实现相同文件名不同md5值的文件在创建个 以"文件名" 为名称的 "文件夹" 下面  在创建多个子文件夹 来存放这些个文件
作者: garyng    时间: 2011-10-11 13:47

回复 4# gie


   没必要使用MD5吧~   除非要排除“相同MD5”但“不同文件名的文件”

   搂主挺聪明的,这东西我正需要呢!
作者: CrLf    时间: 2011-10-11 20:41

主要是效率问题啊,面对大量文件一个个算 MD5 的速度太慢了,所以只能是小范围使用,而若小范围使用,光用 fc /b 就能解决问题了...
感觉 64K 以下的文件最好能不靠 MD5,用 vbs 不换行输出所有文件的十六进制码到文件,然后 sort 排序,估计会快很多,而且也更准确
话说 fastcoll 一出现,MD5 也杯具了
作者: hfg1977    时间: 2011-10-12 09:51

这就是处理对象的不同要采用不同的方法.

比如: 作为一个集图爱好者我有100+G的图片, 已经有其MD5文件, 当我在收集到1000张图片时, 只需计算这1000张的MD5, 删除重复的, 并累积到100+G的MD5文件中.
这样对于后续的图片分类,重命名等都会方便很多...

上述工作我没有找到更好的方法.
作者: conglin58    时间: 2012-2-19 22:21

真是强悍的楼主,强悍的bat
作者: lancer    时间: 2020-9-5 08:55

大神大神,现在win10不是可以直接输入certitul -hashfile 文件 md5,来获取md5吗,是否可以修改一下批处理,不借用第三方的md5.exe呢
作者: Batcher    时间: 2023-8-24 16:46

回复 9# lancer


根据MD5删除当前目录下(不包含子文件夹)重复文件.bat
  1. @echo off
  2. cd /d "%~dp0"
  3. for /f "delims=" %%i in ('dir /b /a-d /od') do (
  4.     for /f %%j in ('certutil -hashfile "%%i" MD5 ^| find /v ":"') do (
  5.         if defined _"%%j" (
  6.             echo del /f /q "%%i"
  7.         ) else (
  8.             set _"%%j"=1
  9.         )
  10.     )
  11. )
复制代码
根据MD5删除当前目录下(包含子文件夹)重复文件.bat
  1. @echo off
  2. cd /d "%~dp0"
  3. for /f "delims=" %%i in ('dir /b /s /a-d /od') do (
  4.     for /f %%j in ('certutil -hashfile "%%i" MD5 ^| find /v ":"') do (
  5.         if defined _"%%j" (
  6.             echo del /f /q "%%i"
  7.         ) else (
  8.             set _"%%j"=1
  9.         )
  10.     )
  11. )
复制代码





欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2