找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 17941|回复: 30

[文件操作] [已解决]hash值查重并手动选择保留的文件

[复制链接]
发表于 2025-6-10 16:44:41 | 显示全部楼层 |阅读模式
本帖最后由 娃娃 于 2025-6-17 21:00 编辑
发现问题?解决问题。



感谢
@77七
提供精准解决方案

以下旧帖编辑于 2025-6-11 17:39

代码来源,先致谢忱:
版权声明:本文为mycoloraa原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/mycoloraa/article/details/113274230
批处理之家以“删除 重复”作关键词,找到(欢迎查缺补漏)并测试可行的代码有@77七及@hfxiang君所写
感谢有你
@77七
第一时间提供核心功能解决方案
@aloha20200628
提供精准核心功能解决方案
心中的方向是或者结合if跟goto语句能成功罢!不成想77七君一个if便起沉疴于既倒。
虽标记为[已解决],但或许锦上添花处尚大有深挖之必要,殷望诸君多多赐教是幸!
不太会说话,设或有何不当之处,诸祈海涵!既云娃娃,童言无忌哈
测试文件夹下清单,不重复的文件实际只有0.txt,1.txt
Episode 01_screenshots\0.txt
Episode 01_screenshots\0 - 複製.txt
Episode 01_screenshots\1.txt
Episode 01_screenshots\1 - 複製.txt
Episode 01_screenshots\o\0.txt
Episode 01_screenshots\o\1.txt
测试文件:Episode 01_screenshots.zip
SHA512:
2d0c97da57e7771f8ee7b7cab28027e77a029398d066cb86279f4ca3c307b89bca02acc3ea81a2d0e5fbeffff7c73c868f87a1b0390616a893024847af7e2fba

  1. @echo off
  2. title 同Cryptographic hash function輸出檔案:留取唯一,芟夷其餘 %DATE% 編譯 %TIME% 執行
  3. rem 視窗標題,運行時顯示
  4. rem 設置保存 SHA512 分析檔案名
  5. set "sha_tmp=__tmp_sha.txt"
  6. rem 設置運行結果檔案名
  7. set "mv_tmp=__tmp_mv.txt"
  8. rem 設置反向移動檔案名
  9. set "tmp_mv=__mv_tmp.cmd"
  10. type nul>%sha_tmp%

  11. set /a n=0
  12. set /a m=0
  13. rem 将变量 m 初始化为整数值 0
  14. setlocal enabledelayedexpansion
  15. rem 启用延迟变量扩展,允许在代码块内实时获取变量更新值。
  16. for %%A in ("%~dp0..") do set "parentDir=%%~fA"
  17. rem 获取当前脚本所在目录的父目录路径。%~dp0:获取当前脚本的绝对路径含结尾反斜杠,..:指向父目录的相对路径,%%~fA:将路径格式化为完整绝对路径

  18. rem 第一步 遍历文件夹下所有文件,找出文件大小相同的文件
  19. echo 读取所有文件的字节大小
  20. for /r %%i in (*) do (
  21. set "fullPath=%%i"
  22. set "relativePath=!fullPath:%parentDir%=!"
  23. set /a m+=1
  24. rem 对变量m执行自增运算。相当于m=m+1,/a参数表示进行算术运算,常用于循环计数或条件触发统计
  25. echo !relativePath! [%%~zi]
  26. rem 输出当前循环变量%%i。通常是文件路径。%%~zi会扩展为文件大小。字节数
  27. if /i not defined s[%%~zi] (
  28. rem 检查以文件大小为索引的数组变量是否已定义
  29. set s[%%~zi]=%%i
  30. rem 若未定义则将当前文件路径存入s[文件大小]变量
  31. ) else (
  32. rem 当检测到相同文件大小时进入else分支
  33. if not defined [%%i] (
  34. rem 检查当前路径是否已记录
  35. set /a n+=1
  36. set [%%i]=a
  37. set "f[!n!]=%%i"
  38. rem 若为新路径则递增计数器n并存入f[]数组
  39. )
  40. if not defined [!s[%%~zi]!] (
  41. rem 检查最初记录的同大小路径是否已处理
  42. set /a n+=1
  43. set [!s[%%~zi]!]=a
  44. set "f[!n!]=!s[%%~zi]!"
  45. rem 同样会递增计数器并记录到f[]数组
  46. )
  47. )
  48. )
  49. echo 總計檔案數量: !m! >> .\%mv_tmp%
  50. echo.
  51. rem 获得大小相同的檔案
  52. echo !n! : 0 需要SHA512分析的總數量 : 已分析數量
  53. rem 第二步 获得大小相同的檔案的SHA512值,并保存至檔案中。
  54. for /l %%i in (1, 1, !n!) do (
  55. set /p k=!f[%%i]!^|<nul
  56. CertUtil -hashfile "!f[%%i]!" SHA512|find /v ":"
  57. )>>%sha_tmp%&echo !n!: %%i "!f[%%i]!"
  58. rem 如果需要使用SHA512 可以更改成 CertUtil -hashfile "!f[%%i]!" SHA512|find /v ":"
  59. endlocal

  60. echo.
  61. setlocal enabledelayedexpansion
  62. rem 获取cmd文件所在目录
  63. for %%b in ("%~dp0.") do set "parentDir=%%~dpb"
  64. set "parentDir=!parentDir:~0,-1!"
  65. rem cmd文件所在目录: %parentDir%
  66. set h=%time:~0,2%
  67. set h=%h: =0%
  68. set dirTmp="%parentDir%\_tmp_%h%%time:~3,2%%time:~6,2%"
  69. rem 相同檔案會移動到的臨時目錄。cmd文件父目錄下,驅動器根目錄或許會出現未知錯誤
  70. md %dirTmp%
  71. echo 創建臨時保存目錄 %dirTmp%
  72. rem 创建反向移动,用于把檔案移动回原来位置的批处理檔案,当需要时可以把txt改成cmd执行
  73. echo @echo off > %dirTmp%\%tmp_mv%

  74. set /a n=0
  75. rem 初始化用于统计重复文件数量的计数器
  76. setlocal enabledelayedexpansion
  77. rem 读取分析好的檔案,对比SHA512来确认檔案是否相同
  78. for /f "tokens=1,2 delims=|" %%i in (.\%sha_tmp%) do (
  79. rem 从%sha_tmp%文件读取数据。格式应为文件路径|哈希值
  80. if not defined [%%j] (
  81. rem 使用[%%j]数组存储首次出现的哈希值对应的文件路径
  82. set "[%%j]=%%i"
  83. ) else (
  84. set /a n+=1
  85. echo %%i
  86. move /y "%%i" "%dirTmp%"
  87. echo move /y "%%~nxi" "%%~dpi" >> %dirTmp%\%tmp_mv%
  88. rem 该命令是批处理脚本中用于生成移动文件指令。%%~nxi:提取循环变量的文件名和扩展名。%%~dpi:提取循环变量的驱动器和路径。/y:强制覆盖目标文件不提示。>> %dirTmp%\%tmp_mv%:将命令追加到指定临时文件。路径变量需提前定义。实际执行需通过call %dirTmp%\%tmp_mv%调用生成的临时文件。若目标路径含空格必须保留引号
  89. echo 相同: ![%%j]! >> .\%mv_tmp%
  90. rem 该命令是 Windows 批处理脚本中用于记录重复项检测结果的指令。![%%j]!:延迟扩展变量(需配合 setlocal enabledelayedexpansion)。>>:追加重定向到临时日志文件。.\%mv_tmp%:当前目录下的环境变量定义文件。需先启用延迟扩展:setlocal enabledelayedexpansion。变量 %%j 需在外部循环中定义。建议路径添加引号:>> ".\%mv_tmp%"
  91. echo 移動: %%i >> .\%mv_tmp%
  92. rem 这条命令是 Windows 批处理脚本中用于记录文件移动操作的指令。%%i:表示 for 循环中的迭代变量(需在批处理文件中使用双百分号)。>>:追加重定向符号(将输出追加到文件末尾)。.\%mv_tmp%:当前目录下的临时文件(路径包含环境变量)。需要先定义 %mv_tmp% 变量。循环变量在批处理脚本中必须使用 %%i(直接命令行执行用 %i)。路径中的特殊字符建议用引号包裹(如 >> ".\%mv_tmp%")
  93. )
  94. )
  95. echo.
  96. echo 總計移動: !n! 檔案至 %dirTmp%
  97. rem 该命令是 Windows 批处理中用于输出文件移动统计信息的指令。!n!:延迟扩展变量(需配合 setlocal enabledelayedexpansion 使用)。%dirTmp%:环境变量表示的目录路径。动态显示变量 n 记录的移动文件计数。需确保 %dirTmp% 已正确定义
  98. echo 總計移動: !n! >> .\%mv_tmp%
  99. endlocal
  100. rem endlocal 是 Windows 批处理脚本中的关键命令,用于恢复环境变量的本地化作用域。与 setlocal 命令配对使用。还原由最近 setlocal 开启的环境变量状态(包括路径、变量值等)。同时会隐式执行 endlocal 之前的 popd 命令

  101. rem echo.&echo 按任意鍵退出...&pause>nul
  102. rem exit
  103. rem 退出
  104. rem if exist "%dirTmp%" rd /s /q "%dirTmp%"
  105. rem 验证%dirTmp% 变量指向的目录有效,删除 %dirTmp% 变量指向的目录,包括目录内所有子文件夹和文件(即使非空)。rd/rmdir:删除目录命令(Remove Directory)。/s:递归删除子目录和文件。"%dirTmp%":环境变量表示的目录路径(需确保已定义)
  106. rem del /q "__tmp_sha.txt"
  107. rem del /q "__tmp_mv.txt"
  108. rem 静默删除当前目录下名为 __tmp_sha.txt、__tmp_mv.txt 的文件。/q 参数表示安静模式(不提示确认)
复制代码
运行以上代码,输出测试文件夹下清单,不重复的文件除了cmd所在目录下
Episode 01_screenshots\0.txt
Episode 01_screenshots\1.txt
二个文件外,其余重复文件都被移动去了cmd所在目录父目录下的临时文件夹内了。
这里请论坛里面的前辈们帮忙看看,新白是不是冗余设置了?
  1. for %%A in ("%~dp0..") do set "parentDir=%%~fA"
  2. rem 获取当前脚本所在目录的父目录路径。%~dp0:获取当前脚本的绝对路径含结尾反斜杠,..:指向父目录的相对路径,%%~fA:将路径格式化为完整绝对路径
复制代码
  1. rem 获取cmd文件所在目录
  2. for %%b in ("%~dp0.") do set "parentDir=%%~dpb"
  3. set "parentDir=!parentDir:~0,-1!"
  4. rem cmd文件所在目录: %parentDir%
  5. set h=%time:~0,2%
  6. set h=%h: =0%
  7. set dirTmp="%parentDir%\_tmp_%h%%time:~3,2%%time:~6,2%"
  8. rem 相同檔案會移動到的臨時目錄。cmd文件父目錄下,驅動器根目錄或許會出現未知錯誤
复制代码

是否可以优化?
@mycoloraa前辈的原代码实现了:第一步,遍历文件夹下所有文件,找出文件字节大小相同的文件;第二步,获得大小相同文件的hash值并自动保留一个,移动其余相同的文件至临时文件夹。
无独有偶,看到@aloha20200628君
对图片/音频/视频去重是个常用操作,尤其是用文件的哈希值(md5)比对去重是个比较高效的方法,但用批处理脚本实现,至少有两个很有用的经验可供参考》
一。应该先对目标目录中的文件按尺寸排序,以便能够忽略其中大部分尺寸相异者,若舍此而去遍历每个文件计算其哈希值,当文件量过千后就有些难受了。例如,5000个文件去重了10个,即可估算前后两种方法所需哈希值计算量的效率之差了。
二。采用纯P的“字典”数据表来对应所有处理对象,比折腾外部数据交换的效率高很多,但会受限于CMD的8k个变量总空间,也就是处理对象/文件数量不要超过此限。好在个人家用较少有单个目录文件量超过此限,因此,单个目录的文件去重,对于纯P是可以驾驭的。
的精辟见解,几疑@mycoloraa前辈与@aloha20200628二而一,一而二矣!不者,两位前辈当真是英雄所见略同了!
如今的想法是:
希望增加在获得大小相同文件的hash值这一步之后,能实现CMD视窗按照重复组别弹出选择项,示例中0.txt这一组3个文件,假设这时候选择保留Episode 01_screenshots\o\0.txt这个文件后,其余的文件CMD执行删除或者暂时移动至临时文件夹均可
Episode 01_screenshots\0.txt
Episode 01_screenshots\0 - 複製.txt
Episode 01_screenshots\o\0.txt
完成示例中0.txt这一组3个文件的处理(这里如果是选择后暂不处理,待完成所有选择后再全部组别一起处理也可以)后,再继续示例中1.txt这一组3个文件的处理,假使这次选择保留Episode 01_screenshots\1.txt这个文件后,其余的文件CMD执行删除或者暂时移动至临时文件夹均可
Episode 01_screenshots\1.txt
Episode 01_screenshots\1 - 複製.txt
Episode 01_screenshots\o\1.txt
以此类推
需要保留.cmd执行完关闭后自动清空临时文件及目录的功能的开关,以上为测试示例故而关闭了该命令。通常测试无纰漏才放心开启
以上核心功能都实现的情况下,若还能添加文件名含“複製(副本)”“(1)”…等hash值相同文件不请示直接删除。hash值相同文件批量按文件名长短,文件所在目录长短,文件创建、修改时间删除的功能,那就越发锦上添花了。
当初测试成功@aloha20200628前辈提取影片长度批处理+js混编获取影片简报.cmd时,心下存了一点猜想:.cmd是否比.bat更具优势?拜读过@youxi01前辈的“由于.bat文件是基于16平台下的程序,在Windows NT及以后的32位中运行时偶尔会出现堆栈溢出之类的错误,所以建议在新的系统中尽可能的采用.cmd扩展的批处理文件代替.bat的文件。”终使胸中块垒得消。
发表于 2025-6-10 23:47:03 | 显示全部楼层
是不是冗余设置了? 不是 ,差别是第1个比第2个就是末尾多了个英文反斜杠
是否可以优化? 可以是可以 ,但是这两个对应的部分是相互独立的 ,耦合性低 ,可单独使用 ,最好不要优化
简单使用文件hash值对图片/音频/视频之类的进行去重的话 ,并不准确 ,例如同一张 ,一张被保存为png格式 ,一张被保存为bmp格式 ,虽然hash不同 ,但是却是相同的
如今的想法是:
希望增加在获得大小相同文件的hash值这一步之后,能实现CMD视窗按照重复组别弹出选择项

CMD视窗的显示是有上限的 ,相同文件一旦多了 ,显示不全的话根本就选不了
 楼主| 发表于 2025-6-11 14:41:59 | 显示全部楼层
回复 2# Five66



谢谢分解!那就不必汲汲于优化了。其实相对于图形界面查重软件动不动几十几百MB(没太注意有没有上GB的),这个脚本已经轻量化的微乎其微了。





hash不同 ,算是不同了吧!或者说这两种格式的曾经出自相同的源头吧。源头好像没法靠简单的方式追溯。


确实未曾考虑到不胜枚举这一点,那只能退而求其次,选择hash值相同文件批量按文件名长短,文件所在目录长短,文件创建、修改时间删除了。

发表于 2025-6-11 14:55:28 | 显示全部楼层
本帖最后由 77七 于 2025-6-11 15:06 编辑
  1. @echo off
  2. cd /d "%~dp0"
  3. (for /f "delims=" %%i in ('dir /b /s /a-d') do (
  4.         if "%%~fi" neq "%~f0" (
  5.                 if "%%~zi" neq "0" (
  6.                         set s=00000000000000000000000000000%%~zi
  7.                         set n=%%i
  8.                         setlocal enabledelayedexpansion
  9.                         echo !s:~-20! !n!
  10.                         endlocal
  11.                 )
  12.         )
  13. )) > "%temp%\$.list.txt"
  14. setlocal enabledelayedexpansion
  15. >"%~dp0\$.del.bat" echo exit
  16. (for /f "tokens=1*" %%h in ('sort "%temp%\$.list.txt" ^& echo 0 0') do (
  17.         if "!s!" equ "%%h" (
  18.                 set n=!n! "%%i"
  19.                 set /a m+=1
  20.         ) else (
  21.                 if !m! geq 1 (
  22.                         set m=0
  23.                         for %%a in (!n!) do (
  24.                                 for /f "delims=" %%b in ('certutil -hashfile "%%~a" MD5 ^| find /v ":"') do (
  25.                                         if defined _"%%b" (
  26.                                                 set _"%%b"=!_"%%b"! "%%~a"
  27.                                         ) else (
  28.                                                 set "_"%%b"=|"%%~a""
  29.                                         )
  30.                                 )
  31.                         )
  32.                         for /f "tokens=1-2 delims=|" %%a in ('set _') do (
  33.                                 if not exist "%%b" (
  34.                                         for %%c in (%%b) do (
  35.                                                 echo del "%%~c"
  36.                                         )
  37.                                         echo=
  38.                                 )
  39.                                 set "%%a"
  40.                         )
  41.                 )
  42.                 set n="%%i"
  43.         )
  44.         set s=%%h
  45. )) >> "%~dp0\$.del.bat"
  46. del "%temp%\$.list.txt"
  47. endlocal
  48. pause
复制代码

执行上面的bat后,会生成一个 $.del.bat,其中按空行分组,组内为重复文件,删除需要保留的文件所在行,删除第一行的exit后,再执行。

评分

参与人数 1技术 +1 收起 理由
娃娃 + 1 君也小白,人何以堪!特谦了。

查看全部评分

 楼主| 发表于 2025-6-11 15:16:11 | 显示全部楼层
回复 4# 77七


   着手回春啊!今番总算由我不由它(脚本)
发表于 2025-6-11 16:35:17 | 显示全部楼层
本帖最后由 aloha20200628 于 2025-6-11 18:00 编辑

回复 1# 娃娃

也给一个简化版本试试...
第一步》先在当前目录及其子目录中查找所有文件尺寸相同且哈希值相同的组别
第二步》逐组处理,列表每组重复文件的 文件序号/修改时间/全路径名,提示选择其中要保留的文件序号,并检查输入合法性
第三步》删除所有未予保留的重复文件
被处理文件类型可在代码第2行自行添加(预设为 *.txt, *.bat);哈希值类型可在代码第5行自定义(预设 sha256,可选 md5, sha512, ...)

  1. @echo off &setlocal enabledelayedexpansion &echo,正在处理...
  2. for /r %%F in (*.txt, *.bat) do if not defined _#%%~zF (set "_#%%~zF="%%F"") else (set "_#%%~zF=!_#%%~zF!,,,"%%F"")
  3. for /f "tokens=1* delims==" %%a in ('set _#^|find ",,,"') do (
  4.   for %%x in (%%b) do (
  5.     for /f "delims=" %%h in ('certutil -hashfile "%%~fx" sha256^|find /v ":" ') do (set "h=%%h" &set "h=!h: =!")
  6.     for %%h in (!h!) do if not defined _h%%h (set "_h%%h="%%~fx"") else (set "_h%%h=!_h%%h!,,,"%%~fx"") )
  7.   set "n=" &for /f "tokens=1* delims==" %%f in ('set _h^|find ",,,"') do for %%x in (%%g) do (
  8.     set/a "n+=1" &set "_f!n!=%%~fx" &echo,!n!》%%~tx %%~fx)
  9.   set "_n=" &for /l %%n in (1,1,!n!) do set "_n=!_n!%%n"
  10.   set/a "_q=n+1" &choice /c !_n!q /m "以上列表中请指定一个要保留的文件序号,q=退出"
  11.   set "v=!errorlevel!" &if !v! neq !_q! for /l %%n in (1,1,!n!) do if %%n neq !v! (del /q "!_f%%n!")
  12.   for /f "delims==" %%v in ('set _h') do set "%%v=" ) 2>nul
  13. exit/b
复制代码

评分

参与人数 1技术 +1 收起 理由
娃娃 + 1 一何善哉!夫复何求!

查看全部评分

 楼主| 发表于 2025-6-11 17:20:15 | 显示全部楼层
回复 6# aloha20200628


   行人更在青山外!芝麻开门节节高。这回真自动了
 楼主| 发表于 2025-6-16 16:16:53 | 显示全部楼层
回复 6# aloha20200628

实际使用过后又发现简直是欲壑难填@aloha20200628君有时间请帮忙看看是否可以完善:
1》2024/09/16 下午 03:45 \1\11\2\2\145.txt
2》2024/12/02 上午 12:44 \1\12\144.txt
以上列表中请指定一个要保留的文件序号,q=退出 [1,2,Q]?1
1》2024/09/16 下午 03:48 \1\11\2\2\33.txt
2》2024/12/02 上午 12:44 \1\12\32.txt
以上列表中请指定一个要保留的文件序号,q=退出 [1,2,Q]?1
1》2024/09/16 下午 03:45 \1\11\2\2\118.txt
2》2024/12/02 上午 12:44 \1\12\117.txt
以上列表中请指定一个要保留的文件序号,q=退出 [1,2,Q]?
情景:
第一次和第二次出现的时候,实际查阅文件后决定保留\1\11\2\2\目录下文件。
第三次出现的时候,可不可以提示以后都保留\1\11\2\2\目录下的文件?
发表于 2025-6-16 16:49:26 | 显示全部楼层
回复 8# 娃娃

先简单理解为要在每次提示中都注明 \1\11\2\2\目录,如此可修改6楼代码第10行中的提示词如下
   "以上列表中请指定一个要保留的文件序号(须在\1\11\2\2\目录中),q=退出"
楼主可自行定义以上括号中的字段...
 楼主| 发表于 2025-6-16 18:00:05 | 显示全部楼层
回复 9# aloha20200628

1》2024/09/16 下午 03:45 \1\11\2\2\145.txt
2》2024/12/02 上午 12:44 \1\12\144.txt
以上列表中请指定一个要保留的文件序号,q=退出 [1,2,Q]?1
1》2024/09/16 下午 03:48 \1\11\2\2\33.txt
2》2024/12/02 上午 12:44 \1\12\32.txt
以上列表中请指定一个要保留的文件序号,q=退出 [1,2,Q]?1
1》2024/09/16 下午 03:45 \1\11\2\2\118.txt
2》2024/12/02 上午 12:44 \1\12\117.txt
以上列表中请指定一个要保留的文件序号,q=退出 [1,2,Q]?
不好意思!没表达清楚。情景:
第一次和第二次出现的时候,实际查阅文件后决定保留\1\11\2\2\目录下文件。
第三次出现的时候,希望提示这一次以后就不再弹出提示,即之后再遇到 \1\11\2\2\目录与\1\12\目录下的重复文件时,不请示直接保留 \1\11\2\2\目录下的文件,并静默删除\1\12\目录下的文件。
感觉还是太弯弯绕绕了,差不多就是按文件夹保留文件。
发表于 2025-6-16 20:10:33 | 显示全部楼层
回复 10# 娃娃

如此理解为》取消提示及其选择确认,直接保留 \1\11\2\2\ 目录下的重复文件,静默删除其余目录下的重复文件?
 楼主| 发表于 2025-6-16 21:12:46 | 显示全部楼层
回复  娃娃

如此理解为》取消提示及其选择确认,直接保留 \1\11\2\2\ 目录下的重复文件,静默删除其余目 ...
aloha20200628 发表于 2025-6-16 20:10


大概是这样。
1》2024/09/16 下午 03:45 \1\11\2\2\118.txt
2》2024/12/02 上午 12:44 \1\12\117.txt
以上列表中请指定一个要保留的文件序号,q=退出 [1,2,3,4,C,Q]?
3,以上列表中请指定一个要保留的文件夹序号(对应文件序号1所在文件夹。选择该选项,之后2文件夹与12文件夹内重复文件不提示,直接保留2文件夹内重复文件静默删除12文件夹内重复文件)
4,以上列表中请指定一个要保留的文件夹序号(对应文件序号2所在文件夹。选择该选项,之后2文件夹与12文件夹内重复文件不提示,直接保留12文件夹内重复文件静默删除2文件夹内重复文件)
C,撤销重选(应对选错的情况)


假设上面选择3,直接跳到另二个文件夹
1》2024/09/16 下午 03:45 \1\11\2\2\18.txt
2》2024/12/02 上午 12:44 \1\13\17.txt
以上列表中请指定一个要保留的文件序号,q=退出 [1,2,3,4,C,Q]?
3,以上列表中请指定一个要保留的文件夹序号(对应文件序号1所在文件夹。选择该选项,之后2文件夹与13文件夹内重复文件不提示,直接保留2文件夹内重复文件静默删除13文件夹内重复文件)
4,以上列表中请指定一个要保留的文件夹序号(对应文件序号2所在文件夹。选择该选项,之后2文件夹与13文件夹内重复文件不提示,直接保留13文件夹内重复文件静默删除2文件夹内重复文件)
C,撤销重选(应对选错的情况)
……
是不是应该重新发个帖子?但需使用@aloha20200628君的代码?
发表于 2025-6-16 22:11:16 | 显示全部楼层
回复 12# 娃娃

你后来的较多需求已与原帖渐远,还是发一个新帖吧,不必牵连某人的代码,以免干扰更多援助者的思路,关键是要一次性把需求表达清楚、表达完整...
发表于 2025-6-17 10:14:29 | 显示全部楼层
批处理 md5去重 手动选择保留文件、设定意向保留目录
  1. @echo off
  2. cd /d "%~dp0"
  3. for /l %%l in (1,1,500) do (
  4.         set @1"%%l"=1
  5.         set @2"%%ls"=1
  6.         set @2"%%l"=1
  7. )
  8. (for /f "delims=" %%i in ('dir /b /s /a-d') do (
  9.         if "%%~fi" neq "%~f0" (
  10.                 if "%%~zi" neq "0" (
  11.                         set s=00000000000000000000000000000%%~zi
  12.                         set n=%%i
  13.                         setlocal enabledelayedexpansion
  14.                         echo !s:~-20! !n!
  15.                         endlocal
  16.                 )
  17.         )
  18. )) > "%temp%\$.list.txt"
  19. setlocal enabledelayedexpansion
  20. for /f "tokens=1*" %%h in ('sort "%temp%\$.list.txt" ^& echo 0 0') do (
  21.         if "!s!" equ "%%h" (
  22.                 set n=!n! "%%i"
  23.                 set /a m+=1
  24.         ) else (
  25.                 if !m! geq 1 (
  26.                         set m=0
  27.                         for %%a in (!n!) do (
  28.                                 for /f "delims=" %%b in ('certutil -hashfile "%%~a" MD5 ^| find /v ":"') do (
  29.                                         if defined _"%%b" (
  30.                                                 set _"%%b"=!_"%%b"! "%%~a"
  31.                                         ) else (
  32.                                                 set "_"%%b"=|"%%~a""
  33.                                         )
  34.                                 )
  35.                         )
  36.                         for /f "tokens=1-2 delims=|" %%a in ('set _') do (
  37.                                 if not exist "%%b" (
  38.                                         for %%c in (%%b) do (
  39.                                                 if defined $"%%~dpc" (
  40.                                                         set /a cc+=1
  41.                                                         set "#!cc!=     时间<%%~tc>     文件<%%~c>"
  42.                                                 )
  43.                                         )
  44.                                         if defined cc (
  45.                                                 for %%c in (%%b) do (
  46.                                                         if not defined $"%%~dpc" (
  47.                                                                 del "%%~c"
  48.                                                                 echo 因为【意向保留】,已删除 "%%~c"
  49.                                                         )
  50.                                                 )
  51.                                                 if !cc! geq 2 (
  52.                                                         echo=
  53.                                                         echo=
  54.                                                         set #
  55.                                                         echo=
  56.                                                         set /p "cho=以上相同文件,存在于【意向保留目录】内,输入数字保留(#=之间的数字):"
  57.                                                         for /l %%l in (1,1,20) do (
  58.                                                                 if not defined @1"!cho!" (
  59.                                                                         set /p cho=输入错误,重新输入:
  60.                                                                 ) else if !cho! gtr !cc! (
  61.                                                                         set /p cho=输入错误,重新输入:
  62.                                                                 )
  63.                                                         )
  64.                                                         echo=
  65.                                                         for /f "tokens=4 delims=<>" %%x in ('set # ^|findstr /rbvc:"#!cho!="') do (
  66.                                                                 del "%%x"
  67.                                                                 echo 因为【手动选择】,已删除 "%%x"
  68.                                                         )
  69.                                                 )
  70.                                                 for /f "tokens=1* delims==" %%a in ('set #') do (
  71.                                                         set "%%a="
  72.                                                 )
  73.                                         ) else (
  74.                                                 for %%c in (%%b) do (
  75.                                                         set /a cc+=1
  76.                                                         set "#!cc!=     时间<%%~tc>     文件<%%~c>"
  77.                                                 )
  78.                                                 echo=
  79.                                                 echo=
  80.                                                 set #
  81.                                                 echo=
  82.                                                 set /p "cho=以上相同文件,存在于【非意向保留目录】内,输入数字保留(#=之间的数字) 或 输入数字+s(如1s,保留并设为意向保留目录):"
  83.                                                 for /l %%l in (1,1,20) do (
  84.                                                         if not defined @2"!cho!" (
  85.                                                                 set /p cho=输入错误,重新输入:
  86.                                                         ) else if !cho:s^=! gtr !cc! (
  87.                                                                 set /p cho=输入错误,重新输入:
  88.                                                         )
  89.                                                 )
  90.                                                 echo=
  91.                                                 for /f "tokens=1* delims==" %%x in ('set #') do (
  92.                                                         for /f "tokens=4 delims=<>" %%z in ("%%y") do (
  93.                                                                 if "#!cho:s=!" equ "%%x" (
  94.                                                                         if "!cho:s=!" neq "!cho!" (
  95.                                                                                 set $"%%~dpz"=1
  96.                                                                         )
  97.                                                                 ) else (
  98.                                                                         del "%%z"
  99.                                                                         echo 因为【手动选择】,已删除 "%%z"
  100.                                                                 )
  101.                                                         )
  102.                                                         set "%%x="
  103.                                                 )
  104.                                         )
  105.                                         set cho=
  106.                                         set cc=
  107.                                 )
  108.                                 set "%%a"
  109.                         )
  110.                 )
  111.                 set n="%%i"
  112.         )
  113.         set s=%%h
  114. )
  115. del "%temp%\$.list.txt"
  116. endlocal
  117. pause
复制代码

评分

参与人数 1技术 +3 收起 理由
娃娃 + 3 程途艰辛!

查看全部评分

 楼主| 发表于 2025-6-17 20:32:53 | 显示全部楼层
回复 14# 77七

臻于至善的去重棘途,一路风尘一路有你。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 09:28 , Processed in 0.027020 second(s), 9 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表