标题: [文件操作] [已解决]批处理能否实现删除重复图片 [打印本页]
作者: a475012621 时间: 2023-8-7 13:45 标题: [已解决]批处理能否实现删除重复图片
首先我有一个大的文件夹,然后里面有很多个子文件夹,然后子文件夹里面有很多照片
,然后每一个单独的子文件夹里有很多重复的照片,但是名字不同
,然后还有就是有可能在其他子文件夹中也会存在其他文件夹里的相同的照片
,现在我最终的诉求是想要每个子文件夹里单独查重就行了,然后完全重复的把它直接删掉,然后我不需要进行全文件夹都去比对,我只需要每一个子文件夹去单独和自己文件夹内的图片进行比对就行了,可以有办法实现吗?求集思广益写个代码~~~
作者: a475012621 时间: 2023-8-7 13:45
回复 1# a475012621
由于测试附件太大了无法上传
作者: a475012621 时间: 2023-8-7 13:48
链接:https://pan.baidu.com/s/1r2u8rqj_2Q6i5dHHNmq0fQ?pwd=gjzl
提取码:gjzl
--来自百度网盘超级会员V2的分享
作者: a475012621 时间: 2023-8-7 13:48
回复 3# a475012621
这是测试文件
作者: czjt1234 时间: 2023-8-7 13:55
每一个子文件夹去单独和自己文件夹内的图片进行比对就行了
这个是根据文件名有 副本(x) 字样来判断吗?
作者: wanghan519 时间: 2023-8-7 14:00
本帖最后由 wanghan519 于 2023-8-7 14:05 编辑
用的powershell,请小心测试,大概意思就是对每个子文件夹建个字典d,然后检查图片的md5码,是否出现在字典的keys里,如果不曾出现就新建字典项,如果出现就删除文件。。。- dir A-* -Directory | % {$d=@{};dir $_ | sort -Descending | % {$m=(Get-FileHash $_.FullName -Algorithm MD5).Hash;if($d.ContainsKey($m)){rm $_.FullName}else{$d.Add($m,1)}}}
复制代码
作者: Five66 时间: 2023-8-7 14:13
文件名带“副本”两个字
和对应的不带“副本”两个字
是否真的全都是相同的
作者: qixiaobin0715 时间: 2023-8-7 14:52
本帖最后由 qixiaobin0715 于 2023-8-7 15:17 编辑
如果只是删除文件名中含有“副本”字样的图片文件,将批处理文件另存为ANSI编码,放在主文件夹中运行:复制代码
作者: a475012621 时间: 2023-8-7 15:30
回复 5# czjt1234
不是,我的意思是图片内容一样,文件名有没得副本不重要
作者: a475012621 时间: 2023-8-7 15:31
回复 8# qixiaobin0715
不是的,和文件名无关,这是我复制出来用来测试的,我是想删除内容相同的图片
作者: a475012621 时间: 2023-8-7 15:36
回复 6# wanghan519
用power shell 测试了一下,好像可以实现删除重复的
作者: a475012621 时间: 2023-8-7 15:54
回复 6# wanghan519
但是有个问题是我如果子文件夹下不止一级目录的话,就报错
作者: a475012621 时间: 2023-8-7 15:55
回复 7# Five66
图片内容相同,文件名不同
作者: wanghan519 时间: 2023-8-7 16:00
本帖最后由 wanghan519 于 2023-8-7 16:07 编辑
回复 12# a475012621
如果说A-1里面的子文件夹一起考虑去重那大概是- dir A-* -Directory | % {$d=@{};dir $_ -File -Recurse | sort -Descending | % {$m=(Get-FileHash $_.FullName -Algorithm MD5).Hash;if($d.ContainsKey($m)){rm $_.FullName}else{$d.Add($m,1)}}}
复制代码
如果A-1里的子文件夹也要分别去重,大概是- dir A-* -Directory | % {$d=@{};dir $_ -File -Recurse | sort -Descending | % {$m=$_.DirectoryName+"\"+(Get-FileHash $_.FullName -Algorithm MD5).Hash;if($d.ContainsKey($m)){rm $_.FullName}else{$d.Add($m,1)}}}
复制代码
作者: a475012621 时间: 2023-8-7 16:21
回复 14# wanghan519
感谢感谢,可以实现了
作者: a475012621 时间: 2023-8-16 21:09
回复 14# wanghan519
大佬,为啥我换了一台电脑就无法使用了呢?使用同样的方法,这台电脑就没有任何反应了
作者: wanghan519 时间: 2023-8-17 04:10
本帖最后由 wanghan519 于 2023-8-17 04:13 编辑
回复 16# a475012621
可能是win7里的powershell版本低,不支持一些参数,好像-File就不行,需要稍微改一下,或者下载压缩包的pwsh7版本
或者用busybox-w32,这个好处是可以把sh脚本打包进exe,单独一个600K的exe,放到哪都能用,代码如下,需要小心测试- cd 目标文件夹
- find . -type f -exec md5sum {} \; | tac | awk '{m=$1;$1="";sub("^ *","");n=$0;"dirname \""n"\"" | getline;if(++d[$0"/"m]>1){system("rm \""n"\"")}}'
复制代码
作者: a475012621 时间: 2023-8-17 09:47
回复 17# wanghan519
好的,感谢了,我两个系统都是win10的,版本应该也是一样的,不理解为啥有一台电脑运行不上,转成exe当然好,但是我搜了一下busybox安装,有点搞不懂,谢谢啦,我再琢磨琢磨
作者: wanghan519 时间: 2023-8-17 10:20
回复 18# a475012621
powershell不能运行需要看一下报错是什么。。。
busybox-w32不需要安装,下载个busybox.exe,命令行运行busybox.exe ash后执行上面那串代码就可以,如果要打包需要安装mingw环境,然后把上面那段代码放到文本里,存入项目目录下embed文件夹,再make,出来的busybox.exe就包含那段脚本,可以改名成那个脚本名.exe直接运行,也可以当成busybox.exe来用
作者: a475012621 时间: 2023-8-17 10:34
回复 19# wanghan519
好嘛,我去试试,powershell运行的话,没有提示错误,但是代码运行了就是没得任何反应,其他没有提示
作者: a475012621 时间: 2023-8-19 10:43
本帖最后由 a475012621 于 2023-8-19 10:44 编辑
回复 19# wanghan519
https://postimg.cc/B8t8H0Bp我改变路径它说找不到
作者: Batcher 时间: 2023-8-19 11:11
回复 18# a475012621
请在你的两位Win10的PowerShell命令行里分别执行命令:复制代码
复制代码
截图发出来看看
作者: wanghan519 时间: 2023-8-19 11:29
回复 21# a475012621
这图中是试用busybox ash,这是个Linux shell,要区分大小写,所以大写的CD找不到命令,cd 路径,路径也要注意大小写
作者: a475012621 时间: 2023-8-19 11:34
回复 22# Batcher
https://postimg.cc/GHjYwr33
作者: a475012621 时间: 2023-8-19 11:35
回复 22# Batcher
https://postimg.cc/1nx4VYRY
作者: a475012621 时间: 2023-8-19 11:46
回复 22# Batcher
作者: a475012621 时间: 2023-8-19 11:47
回复 26# a475012621
运行了,它没有报错,但是文件并没有做更改
作者: a475012621 时间: 2023-8-19 11:47
回复 23# wanghan519
好的,我试试
作者: wanghan519 时间: 2023-8-19 11:59
回复 27# a475012621
可以上传两个没被删除的相同的图片到网盘吗,可能md5sum有些不同
作者: 77七 时间: 2023-8-19 12:09
本帖最后由 77七 于 2023-8-19 12:34 编辑
也可以使用第三方工具获取MD5
- http://bcn.bathome.net/tool/fourmilab,2.0/md5.exe
复制代码
- @echo off
- for /r /d %%d in (*) do (
- pushd "%%d"
- setlocal
- for /f "tokens=1*" %%a in ('"%~dp0md5.exe" *.jpg') do (
- if defined _"%%a" (
- del "%%b"
- ) else (
- set _"%%a"=1
- )
- )
- endlocal
- popd
- )
- pause
复制代码
作者: buyiyang 时间: 2023-8-19 13:45
回复 30# 77七
用自带的certutil就可以计算各类哈希值
作者: 77七 时间: 2023-8-19 14:08
回复 31# buyiyang
谢谢大佬指点!重新写了一个。- @echo off
- rem http://bbs.bathome.net/redirect.php?goto=findpost&ptid=53343&pid=221896
- for /r /d %%d in (*) do (
- pushd "%%d"
- setlocal
- for %%a in (*.jpg) do (
- for /f %%i in ('certutil -hashfile "%%a" MD5 ^| findstr /v "[^0-9a-z]"') do (
- if defined _"%%i" (
- del "%%a"
- ) else (
- set _"%%i"=1
- )
- )
- )
- endlocal
- popd
- )
- pause
复制代码
作者: aloha20200628 时间: 2023-8-19 20:05
对图片/音频/视频去重是个常用操作,尤其是用文件的哈希值(md5)比对去重是个比较高效的方法,但用批处理脚本实现,至少有两个很有用的经验可供参考》
一。应该先对目标目录中的文件按尺寸排序,以便能够忽略其中大部分尺寸相异者,若舍此而去遍历每个文件计算其哈希值,当文件量过千后就有些难受了。例如,5000个文件去重了10个,即可估算前后两种方法所需哈希值计算量的效率之差了。
二。采用纯P的“字典”数据表来对应所有处理对象,比折腾外部数据交换的效率高很多,但会受限于CMD的8k个变量总空间,也就是处理对象/文件数量不要超过此限。好在个人家用较少有单个目录文件量超过此限,因此,单个目录的文件去重,对于纯P是可以驾驭的。
作者: a475012621 时间: 2023-8-19 23:57
回复 29# wanghan519
链接:https://pan.baidu.com/s/1NK6rIHtoy1QLbsnoMYTRyw?pwd=ixl0
提取码:ixl0
--来自百度网盘超级会员V2的分享
作者: a475012621 时间: 2023-8-20 00:05
回复 32# 77七
感谢,可以了
作者: Five66 时间: 2023-8-20 01:13
回复 32# 77七
不知为啥,我这边运行时,第7行for in里面那句certutil -hashfile "%%a" MD5 ^| findstr /v "[^0-9a-z]" 结果总是空的
作者: 77七 时间: 2023-8-20 01:48
回复 36# Five66
0字节文件好像不能获取md5
作者: Five66 时间: 2023-8-20 01:55
回复 37# 77七
不是0字节文件,不知道是不是是系统问题,我这里(不是win10系统)输出的md5好像是带有空格的:
输出是这样的:
MD5 hash of file 33.jpg:
71 51 39 e0 db b7 2e f2 89 ce 4a 3c 02 92 7b 50
CertUtil: -hashfile command completed successfully.
作者: 77七 时间: 2023-8-20 02:03
回复 38# Five66
改为find /v ":",过滤,可能更好,看了好几个帖子,都用的findstr
作者: Five66 时间: 2023-8-20 02:10
回复 39# 77七
findstr /e "[0-9a-z]" 也能过滤,不过还得处理空格
作者: wanghan519 时间: 2023-8-20 04:32
回复 34# a475012621
修改了一下powershell代码,一会再试试先比较大小,再算md5,以加快速度- cd 测试
- $d=@{};dir -File -Recurse | sort -Descending | % {$m=$_.DirectoryName+"\"+(Get-FileHash $_.FullName -Algorithm MD5).Hash;if($d.ContainsKey($m)){rm $_.FullName}else{$d.Add($m,1)}}
复制代码
作者: a475012621 时间: 2023-8-20 10:55
回复 41# wanghan519
谢谢,费心了,应该没问题了
作者: aloha20200628 时间: 2023-8-20 13:30
本帖最后由 aloha20200628 于 2023-8-20 14:12 编辑
如此设置 findstr 的匹配参数,还为防止目标文件名出现 “e3 b4 a5.jpg” 的特殊情况...- certutil -hashfile "1.jpg" md5 | findstr /rbc:"[0-9a-z][0-9a-z] "
复制代码
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |