我正在寻找一种简单的方法(一个命令或一系列命令,可能涉及find)在两个目录中查找重复文件,并将一个目录中的文件替换为另一目录中文件的硬链接。

这里的情况:这是一个文件服务器,多个人在上面存储音频文件,每个用户都有自己的文件夹。有时,多个人拥有完全相同的音频文件的副本。现在,这些是重复的。我想使其成为硬链接,以节省硬盘空间。

评论

硬链接可能会遇到的一个问题是,如果有人决定对其硬链接的音乐文件之一做某事,他们可能会无意中影响其他人对其音乐的访问。
另一个问题是,即使包含相同编码器的同一来源的两个文件,其中包含“ Some Really Great Tune”的两个文件也很可能不完全相同。
更好的解决方法可能是拥有一个公共音乐文件夹...

相关:superuser.com/questions/140819/ways-to-deduplicate-files

@tante:使用符号链接不会解决任何问题。当用户“删除”文件时,指向该文件的链接数会减少,而当计数达到零时,文件实际上会被删除,仅此而已。因此删除对于硬链接的文件来说没有问题,唯一的问题是用户试图编辑文件(实际上不太可能)或覆盖文件(如果登录就可以)。

#1 楼

http://cpansearch.perl.org/src/ANDK/Perl-Repository-APC-2.002/eg/trimtrees.pl中有一个perl脚本,它完全可以满足您的需求:


遍历在
命令行上命名的所有目录,计算MD5校验和
并查找具有相同MD5的文件。如果它们相等,则进行真正的比较
,如果确实相等,则将两个文件中的第二个
替换为与第一个文件的硬链接



评论


多完美,谢谢!我将尝试并接受它是否如描述的那样起作用!

–乔什
10-10-12在20:09

这正是我所要求的。但是,我相信使用dedup的ZFS最终将成为解决问题的方法,因为我确实发现文件之间存在细微差别,因此只有少数文件可以进行硬链接。

–乔什
2010年12月8日在20:13

对此表示支持,但是在研究了更多内容之后,我还是没有这样做。 rdfind可通过所有主要平台(os x,linux,(cyg)win,solaris)的软件包管理器使用,并且以惊人的本机速度工作。因此,请查看下面的答案。

–寡核苷酸
2015年1月3日在13:42



@oligofren我在想同样的方法,但是后来我点击了[Errno 31]链接太多。这似乎是唯一解决问题的方法。

– phunehehe
15年6月26日在6:59

对每个文件(而不是仅存在至少一个大小相同的其他文件)进行校验和处理不必要地效率低下(不必要地发生哈希冲突)。

–查尔斯·达菲(Charles Duffy)
16年2月1日在16:56



#2 楼

rdfind确实满足您的要求(并且按johny为什么列出顺序)。使删除重复项成为可能,并用软链接或硬链接替换它们。与symlinks结合使用,您还可以使符号链接成为绝对链接或相对链接。您甚至可以选择校验和算法(md5或sha1)。
由于它经过编译,因此比大多数脚本解决方案都快:time位于15 GiB文件夹中,2009年我的Mac Mini上具有2600个文件,返回此
9.99s user 3.61s system 66% cpu 20.543 total

(使用md5)。
在大多数程序包处理程序中可用(例如,用于Mac OS X的MacPorts)。

评论


+1我使用rdfind并喜欢它。它具有-dryrun true选项,可以让您知道它会做什么。用硬链接替换重复项就像-makehardlinks true一样简单。它产生了一个不错的日志,它让我知道释放了多少空间。另外,根据作者的基准,rdfind比duff和fslint更快。

–丹尼尔·特雷比恩(Daniel Trebbien)
2013年12月29日20:49在

哦,很好。我曾经使用过fdupes,但是在最新的Ubuntu 14.10中缺少用于硬链接dupes的-L选项。速度非常慢,并且在OSX上不适用于Homebrew,因此此答案要好得多。谢谢!

–寡核苷酸
2015年1月3日,13:38

我怀疑此工具的性能与算法本身有关,而与它是编译工具还是脚本无关。对于这种操作,磁盘几乎一直都是瓶颈。只要脚本化工具确保在对CPU进行校验和刻录时正在进行异步I / O操作,它们的性能应与本机二进制文件差不多。

– cdhowie
18年5月31日在21:19

注意,某些版本的rdfind会受到一个非常不便的错误的影响:无法创建硬链接时,源文件将被删除。

–Skippy le Grand Gourou
20年1月2日,17:01



@ d-b我想知道最近不到1.5年的系统比例是多少。我丢失了数据,如果其他人不检查他们的版本,他们也会这样做。他们应该受到警告。

–Skippy le Grand Gourou
20 Mar 23 '20 at 10:08

#3 楼

使用fdupes工具:

fdupes -r /path/to/folder为您提供目录中重复项的列表(-r使其递归)。输出看起来像这样: >
,文件名1和文件名2相同,文件名3,文件名4和文件名5也相同。

评论


Ubuntu注意:截至2013年9月,它尚未发布稳定版本(版本为1.50-PR2-3),因此该更新尚未出现在ubuntu中。

– Stuart Axon
13年8月28日在14:19

我只是尝试在Ubuntu和Debian上安装fdupes_1.50-PR2-4,它们都没有-L标志。幸运的是,从github.com/tobiasschulz/fdupes进行构建非常容易。

– neu242
13年8月30日在15:07

尝试rdfind-类似于fdupes,但速度更快,并且可在OS X和Cygwin上使用。

–寡核苷酸
15年1月3日,13:43

fdupes似乎只能找到重复项,而不能用硬链接代替它们,因此不能解决IMO问题。

–卡利莫
17年11月8日在15:58

有一个类似的基于fdupes的名为jdupes的工具,但是它也可以用符号链接(-l),硬链接(-L)替换重复的文件,或者指示btrfs在文件系统级别对块进行重复数据删除(-B使用btrfs)。

– Marius Gedminas
18年8月22日在16:36



#4 楼

我使用来自http://jak-linux.org/projects/hardlink/
hardlink

评论


很好的提示,我使用的是常规基本代码。google.com/ p / hardlinkpy,但是一段时间未更新了...

– meduz
2012年4月11日19:09

这似乎类似于Fedora / RHEL / etc上的原始硬链接。

–user12810
2012年6月21日上午8:43

hardlink现在是许多Linux软件包系统中的本机二进制文件(自2014年以来),而且速度非常快。对于1,2M个文件(320 GB),只用了200秒(链接了大约10%的文件)。

– Marcel Waldvogel
17年2月5日在19:13

FWIW,上面的硬链接是由朱利安·安德烈斯·克洛德创建的,而Fedora硬链接是由Jakub Jelinek创建的(来源:pagure.io/hardlink-Fedora包名称:hardlink)

–maxschlepzig
19年1月4日在17:52

#5 楼

这是“ fslint”提供的功能之一-
http://en.flossmanuals.net/FSlint/Introduction

单击“合并”按钮:



评论


-m将硬链接复制在一起,-d将删除所有链接,但-t将空运行,打印将执行的操作

–阿岑代尔
2012年10月29日,下午5:57

在Ubuntu上,该怎么做:sudo apt-get install fslint / usr / share / fslint / fslint / findup -m / your / directory / tree(目录/ usr / share / fslint / fslint /默认不在$ PATH中) )

–乔斯林
2013年9月8日15:38



#6 楼

由于您的主要目标是节省磁盘空间,因此还有另一种解决方案:在文件系统级别进行重复数据删除(可能是压缩)。与硬链接解决方案相比,它不存在不经意地影响其他链接文件的问题。
如果您使用的是Linux,则可以尝试zfs-fuse,或者如果您使用的是BSD,则本机支持。

评论


这可能是我最终将要采用的方法,但是BSD的ZFS实现是否可以简化?我以为没有。

–乔什
2010-12-08 20:14

另外,DragonFlyBSD上的HAMMER文件系统具有重复数据删除支持。

– hhaamu
2012年7月15日在17:48



ZFS dedup是没有人的朋友。 ZFS建议每1Tb可用磁盘空间使用1Gb内存的地方,如果您尝试使用每1Tb可用磁盘空间使用少于32Gb ram的dedup的话,那您真是疯了。这意味着对于1Tb镜像,如果您没有32 Gb的ram,则很可能迟早会遇到内存炸弹的情况,由于缺少ram,这将使机器停止运行。到那里去了,照做了,仍然从PTSD中恢复过来。

– Killermist
2014-09-22 18:51

为了避免在线重复数据删除(即检查每次写入)对RAM的过多要求,btrfs使用批处理或离线重复数据删除(在您认为有用/必要时运行它)btrfs.wiki.kernel.org/index.php/Deduplication

– Marcel Waldvogel
17年2月5日在19:18

七年后的更新:我最终确实迁移到ZFS并尝试了重复数据删除-我发现它的RAM需求确实确实很高。巧妙地使用ZFS快照提供了我最终使用的解决方案。 (复制一个用户的音乐,快照和克隆,然后使用rsync --inplace将第二个用户的音乐复制到克隆中,这样就只存储更改的块)

–乔什
17年9月13日在13:54

#7 楼

如今,在现代Linux上,有一个https://github.com/g2p/bedup可以在btrfs文件系统上进行重复数据删除,但是1)没有太多的扫描开销,2)之后文件可以很容易地重新发散。

评论


背景和更多信息在btrfs.wiki.kernel.org/index.php/Deduplication上列出(包括对cp --reflink的引用,另请参见下文)

– Marcel Waldvogel
17年2月5日在19:22

#8 楼

要查找重复的文件,可以使用duff。


Duff是Unix命令行实用工具,可以在给定的文件集中快速查找
中的重复项。


只需运行: bash或其他脚本语言。

评论


虽然真的很慢-参见rdfind.pauldreik.se/#g0.6

– ndemou
15年10月30日在12:52

#9 楼

aptitude show hardlink


描述:硬链接同一文件的多个副本
硬链接是一种检测同一文件的多个副本并将其替换为硬链接的工具。

这个想法来自http://code.google.com/p/hardlinkpy/,但是代码是从头开始编写的,并获得了MIT的许可。 http://jak-linux.org/projects/hardlink/

评论


这里提到的唯一可用于Gentoo的程序,无需取消屏蔽即可使用,并具有硬链接支持,谢谢!

–Jorrit Schippers
2015年3月9日在13:48

#10 楼

jdupes已在评论中提及,但值得自己回答,因为它可能在大多数发行版中都可用并且运行非常快(它仅在大约一分钟的时间内释放了2.7GB的158GB完整分区(SSD驱动器)的2.7GB): br />
jdupes -rL /foo/bar


评论


jdupes确实应该是答案。它是快速且可配置的,并且可以随时显示进度。最初扫描时,您可能会很危险(-T -T),而无需修改(-M)来查看可能的用途。然后选择默认大小/部分哈希/完整哈希/逐位比较模式,跳过哈希并直接进入比特(-K),而不会增加任何风险,或者掷骰子并仅在跳过比特时才进行完整哈希比较(-Q)。唯一缺少的是一种交互式模式,您可以在该模式中对每个建议进行排序。我是否提到过速度很快?

–克里斯
20年6月12日,0:36

#11 楼

我使用了这里提到的许多用于Linux的硬链接工具。但是最近在cp手册页中注意到了轻量级副本,这意味着在修改一侧之前要保留冗余磁盘空间:


评论


我想我现在将更新cp别名以始终包含--reflink = auto参数

– Marcos
2012年3月14日14:08

ext4是否真的支持--reflink?

–user12810
2012年6月21日上午8:42

btrfs和OCFS2支持此功能。只能在写时复制文件系统上使用,而ext4则不能。 btrfs确实正在形成。我喜欢使用它,因为它具有reflink和快照功能,使您不必担心对大文件树进行大规模操作。

–clacke
2012年7月3日在18:57

#12 楼

在我看来,首先检查文件名可以加快处理速度。如果两个文件缺少相同的文件名,那么在许多情况下,我不会认为它们是重复的。似乎最快的方法是按顺序比较:


文件名
size 字节内容

这有什么方法吗?查看dufffdupesrmlintfslint等。

以下方法在commandlinefu.com上获得最高投票:查找重复文件(首先基于大小,然后基于MD5哈希) br />可以先添加文件名比较功能,然后再添加文件大小比较功能吗?

find -not -empty -type f -printf "%s\n" | sort -rn | uniq -d | \
  xargs -I{} -n1 find -type f -size {}c -print0 | xargs -0 md5sum | \
  sort | uniq -w32 --all-repeated=separate


评论


我使用了duff,fdupes和rmlint,并强烈建议读者阅读其中的第三篇。它具有出色的选项集(和文档)。有了它,我可以避免很多我需要与其他工具一起使用的后期处理。

– dubiousjim
2015年9月2日在6:32



在我的实践中,文件名是最不可靠的因素,我已将其从重复数据删除的所有工作中完全删除。在活动的系统上可以找到多少个install.sh文件?我无法计算保存文件并发生名称冲突的次数,并且需要进行一些动态重命名来保存它。反面:不知道我在不同的日子从不同来源下载了多少次,却发现它们是同一个文件,但名称不同。 (这也会破坏时间戳的可靠性。)1:大小,2:摘要,3:字节内容。

–辛德拉巴
17年1月28日在6:40

@GypsySpellweaver:(1)取决于个人用例,您不同意吗?就我而言,我有多个备份的多个还原,其中具有相同名称和内容的文件存在于不同的还原文件夹中。 (2)您的评论似乎仅假设比较文件名。我不是在建议取消其他检查。

–约翰尼为什么
17 Mar 8 '17 at 21:50

不要使用rmlint。它发出一个不检查错误的shellscript。它将删除重复项,然后尝试进行硬链接,这可能会失败(例如,由于链接过多),然后继续处理遭受相同命运的下一个重复项。它会吞噬您的文件。正确的方法是使用一个临时名称创建它,然后通过重命名替换副本。

–the8472
20-10-7在10:01



#13 楼

由于我不喜欢Perl,因此这里是bash版本:

 #!/bin/bash

DIR="/path/to/big/files"

find $DIR -type f -exec md5sum {} \; | sort > /tmp/sums-sorted.txt

OLDSUM=""
IFS=$'\n'
for i in `cat /tmp/sums-sorted.txt`; do
 NEWSUM=`echo "$i" | sed 's/ .*//'`
 NEWFILE=`echo "$i" | sed 's/^[^ ]* *//'`
 if [ "$OLDSUM" == "$NEWSUM" ]; then
  echo ln -f "$OLDFILE" "$NEWFILE"
 else
  OLDSUM="$NEWSUM"
  OLDFILE="$NEWFILE"
 fi
done
 


此查找所有具有相同校验和的文件(无论它们是大,小还是已经进行了硬链接),并将它们硬链接在一起。 )和文件缓存(因此您不必每次都重做校验和)。如果有人对更智能,更长的版本感兴趣,可以发布它。 br />

评论


我该如何更改脚本,而不是对其进行硬链接,它只会删除重复的文件,并将已删除文件->内衬文件添加到CSV文件中。 。 ???

– GEWA先生
2013年1月12日12:17



当然。硬链接行:echo ln -f“ $ OLDFILE”“ $ NEWFILE”只需用硬链接替换重复的文件,所以您可以通过$ NEWFILE更改它。

– Seren
2013年1月13日4:15



以及如何在下一行中以某种方式写一些文本文件$ OLDFILE-> NEWFILE ???

– GEWA先生
2013年1月13日13:12



啊,对。是的,在rm之后添加一行,例如:echo“ $ NEWFILE” >> /var/log/deleted_duplicate_files.log

– Seren
2013年1月14日19:28



不要花钱重新发明轮子。有更多成熟的解决方案可用,例如rdfind,它们可以以本机速度运行,仅需要brew install rdfind或apt-get install rdfind即可安装。

–寡核苷酸
15年1月3日,13:46

#14 楼

我制作了一个Perl脚本,它执行的操作与您在说的内容类似:计算其中文件的SHA1sum,对其进行哈希处理并将匹配项链接在一起。它在很多场合都派上用场了。

评论


我希望尽快解决这个问题...为什么不将其上传到CPAN ... App :: relink或其他东西

– xenoterracide
2011-2-7在11:12

@xenoterracide:因为已经存在所有类似且更成熟的解决方案。查看其他答案,尤其是rdfind。

–寡核苷酸
2015年1月3日在13:36



@oligofren我毫不怀疑存在更好的解决方案。我猜是TMTOWTDI。

–amphetamachine
2015年1月5日15:49

#15 楼

如果要在Mac或任何基于UNIX的系统上通过“硬链接”替换重复项,可以尝试SmartDupe http://sourceforge.net/projects/smartdupe/
开发它

评论


您可以扩展它的“智能”程度吗?

–StéphaneGimenez
2012年11月4日13:25

如何比较两个不同目录的文件?

– Burcardo
16年5月31日在8:26

#16 楼

应用程序FSLint(http://www.pixelbeat.org/fslint/)可以在任何文件夹中(按内容)找到所有相等的文件,并创建硬链接。试试看吧!

Jorge Sampaio

评论


它挂起了扫描将近1TB的几乎已满的ext3硬盘的记录,使整个系统爬行。经过14小时的“搜索”后中止

–Angsuman Chakraborty
16年9月12日在11:09

#17 楼

如果您要进行硬链接,请注意该文件的权限。注意,所有者,组,模式,扩展属性,时间和ACL(如果使用的话)存储在INODE中。只有文件名不同,因为文件名存储在目录结构中,其他指向INODE属性。因此,链接到同一索引节点的所有文件名都具有相同的访问权限。您应该防止修改该文件,因为任何用户都可能将文件损坏。很简单。足够了,任何用户都可以使用相同的名称放置其他文件。然后保存索引节点号,并为所有硬链接名称破坏(替换)原始文件内容。更好的方法是在文件系统层上进行重复数据删除。您可以使用BTRFS(上次非常流行),OCFS或类似方法。查看页面:https://zh.wikipedia.org/wiki/Comparison_of_file_systems,特别是在表功能和列重复数据删除中。您可以单击它并进行排序:)

专门查看ZFS文件系统。这可以作为FUSE使用,但这种方式非常慢。如果需要本机支持,请查看页面http://zfsonlinux.org/。然后,您必须修补内核,然后安装用于管理的zfs工具。我不明白,为什么Linux不支持作为驱动程序,这是许多其他操作系统/内核的方法。 ZFS支持块。这意味着,可以删除在同一文件中重复的相同内容。其他方法是对数据进行重复数据删除的时间,该时间可以是联机(zfs)或脱机(btrfs)。

请注意,重复数据消除会消耗RAM。这就是为什么将文件写入通过FUSE挂载的ZFS卷会导致性能显着降低的原因。在文档中对此进行了描述。
但是您可以在线设置卷上的开/关重复数据删除功能。如果看到任何数据应进行重复数据删除,则只需将重复数据删除设置为开,将某些文件重写为任何临时文件,最后替换。之后,您可以关闭重复数据删除并恢复完整性能。当然,您可以将任何缓存磁盘添加到存储中。这可以是非常快速的旋转磁盘或SSD磁盘。当然这可以是很小的磁盘。在实际工作中,这是对RAM的替代:)

在Linux下,您应该注意ZFS,因为并非所有工作都应按其正常工作,特别是在管理文件系统,制作快照等时,但是如果进行配置和不要更改它,一切正常。换句话说,您应该将linux更改为opensolaris,它本身支持ZFS :) ZFS的优点是,它既可以用作文件系统,又可以用作类似于LVM的volumen Manager。使用ZFS时不需要它。如果您想了解更多信息,请参阅文档。

注意ZFS和BTRFS之间的区别。 ZFS更老,更成熟,不幸的是仅在Solaris和OpenSolaris下(不幸的是被oracle扼杀)。 BTRFS较年轻,但上次获得了很好的支持。我建议使用新内核。 ZFS具有在线重复数据删除功能,这会导致写入速度变慢,因为所有内容都是在线计算的。 BTRFS支持离线重复数据删除。这样可以节省性能,但是当主机无关时,您可以定期运行用于重复数据删除的工具。 BTRFS是在linux下本地创建的。也许这对您来说是更好的FS :)

评论


我确实喜欢btrfs拥有的离线(或批处理)重复数据删除方法。在此处对选项(包括cp --reflink选项)进行了精彩的讨论:btrfs.wiki.kernel.org/index.php/Deduplication

– Marcel Waldvogel
17-2-5在19:42

ZFS不仅是Solaris或OpenSolaris。 FreeBSD本身支持它。另外,Linux上的ZFS也是基于设备驱动程序的。 FUSE上的ZFS是另一回事。

– KJ Seefried
18 Mar 29 '18 at 19:07

#18 楼

硬链接可能不是最好的主意。如果一个用户更改了文件,则会同时影响两个文件。但是,删除硬链接不会同时删除两个文件。另外,我不能完全确定Hard Links是否占用与同一文件的多个副本相同的空间(在硬盘上,而不是OS)。根据Windows(带有Link Shell扩展),它们确实可以。当然,那是Windows,而不是Unix ...

我的解决方案是在一个隐藏文件夹中创建一个“公共”文件,然后用符号链接替换实际的重复项...然后,符号链接将嵌入元数据或备用文件流,这些元数据或备用文件流仅记录但两个“文件”彼此不同,例如,如果一个人想要更改文件名或添加自定义专辑封面或类似内容;它甚至可能在数据库应用程序之外很有用,例如安装同一游戏或软件的多个版本,并以最小的差异进行独立测试。

#19 楼

最简单的方法是使用特殊程序
dupeGuru

如文档所述

删除选项
这些选项影响重复删除的方式。
大多数情况下,您不需要启用任何一个。
链接已删除的文件:
已删除的文件将替换为指向参考文件的链接。
您可以选择用符号链接或硬链接替换它。
...
符号链接是文件路径的快捷方式。
如果删除或移动了原始文件,则链接会断开。
硬链接是指向文件本身的链接。
该链接与“真实”文件一样好。
仅当删除与文件的所有硬链接时,文件本身才会被删除。 br />在OSX和Linux上,完全支持此功能,
但是在Windows下,它有点复杂。
Windows XP不支持,但是Vista及以上版本支持。
但是,要使该功能正常工作,
dupeGuru必须具有管理特权才能运行。