Shell 在UNIX中删除相同的文件

Shell 在UNIX中删除相同的文件,shell,file,unix,duplicates,Shell,File,Unix,Duplicates,我正在处理大约10MB大小的大量(30000)文件。其中一些(我估计2%)实际上是重复的,我只需要为每个重复的对(或三联体)保留一个副本。 你能给我一个有效的方法吗?我正在unix上工作。我会编写一个脚本来创建每个文件的哈希。您可以将散列存储在一个集合中,迭代文件,如果文件散列到集合中已找到的值,则删除该文件。例如,在Python中,这样做很简单 对于30000个文件,每个哈希表条目64字节,您只需要查看大约200兆字节。编写一个脚本,首先比较文件大小,然后比较MD5校验和(当然是缓存它们),如

我正在处理大约10MB大小的大量(30000)文件。其中一些(我估计2%)实际上是重复的,我只需要为每个重复的对(或三联体)保留一个副本。
你能给我一个有效的方法吗?我正在unix上工作。

我会编写一个脚本来创建每个文件的哈希。您可以将散列存储在一个集合中,迭代文件,如果文件散列到集合中已找到的值,则删除该文件。例如,在Python中,这样做很简单


对于30000个文件,每个哈希表条目64字节,您只需要查看大约200兆字节。

编写一个脚本,首先比较文件大小,然后比较MD5校验和(当然是缓存它们),如果您非常担心丢失数据,则咬紧牙关,并实际逐字节比较重复的候选文件。如果您对文件是如何产生的等没有更多的了解,那么就无法更有效地执行此操作。

查找可能的重复文件:

find DIR -type f -exec sha1sum "{}" \; | sort | uniq -d -w40

现在,您可以使用
cmp
检查文件是否完全相同。

在删除之前,您可以先尝试此代码段以获取所有重复的文件

find /path -type f -print0 | xargs -0 sha512sum | awk '($1 in seen){print "duplicate: "$2" and "seen[$1] }(!($1 in  seen)){seen[$1]=$2}' 

将所有文件名保存在一个数组中。然后遍历数组。在每次迭代中,使用命令
md5sum
将文件内容与其他文件的内容进行比较。如果MD5相同,则删除该文件


例如,如果文件
b
是文件
a
的副本,则两个文件的
md5sum
将是相同的。

有一个用于此目的的现有工具:fdupes


从旧的已删除答案还原解决方案。

重复可以基于以下1。内容2。文件名你想怎么做?基于文件名的内容:-)太容易了什么是元字节?某种理想化的字节?只有当你有一个完美的散列函数时,你的解决方案才有效。什么不是元字节?固定的。偏执狂可以在删除的情况下比较文件的内容。添加一个额外的散列也会有所帮助。@Neil如果你使用一个现代的、目前尚未中断的加密散列函数,并且你发现一个冲突,你的算法会崩溃,但你已经获得了一张加密纸,所以这一切都是赢的。不过,在删除其中一个之前,比较假定的重复项是值得的。通过简单的计数参数,正确的加密哈希函数并不完美,但您可以将它们视为所有意图和目的所必需的。@Pascal肯定会发生冲突。考虑文件可以被看作是一个非常大的单个二进制数,远远大于散列。冲突是不可避免的,因为散列会丢失信息。这是一个从不同来源下载的高吞吐量文件,所以我得到了一些冗余。我将尝试md5sum,因此我应该为所有这些代码获取哈希代码。我会告诉你,如果它工作:-你可能想考虑算法复杂性的特定方法…-W是GNU UNIQ的一个特点;d只能找到连续的重复项,因此您必须先排序,而不是使用
-w
(这只在GNU中,就像第一条评论所说的那样)。您可以将
sort
的输出通过管道输送到
cut-d \-f 1
,然后将其输送到
uniq-d
。这更便于携带。它将在BSD、OSX和其他系统上工作。@monokrome:Err。。。不,那只会给你没有文件名的校验和。如果没有GNU
uniq
,则必须使用
awk
及其关联数组来模拟
uniq