有没有一种简单的方法可以用硬链接替换重复文件?

Jos*_*osh 173 hard-link files deduplication duplicate-files

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

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

d-b*_*d-b 136

rdfind完全按照您的要求执行(并按照约翰尼为什么列出的顺序)。可以删除重复项,用软链接或硬链接替换它们。结合symlinks您还可以使符号链接成为绝对的或相对的。您甚至可以选择校验和算法(md5 或 sha1)。

由于它是编译的,所以它比大多数脚本解决方案更快:time从 2009 年开始,在我的 Mac Mini 上有 2600 个文件的 15 GiB 文件夹上返回这个

9.99s user 3.61s system 66% cpu 20.543 total
Run Code Online (Sandbox Code Playgroud)

(使用 md5)。

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

  • +1我使用了`rdfind`并喜欢它。它有一个 `-dryrun true` 选项,可以让你知道它会做什么。用硬链接替换重复项就像`-makehardlinks true`一样简单。它生成了一个不错的日志,它让我知道释放了多少空间。另外,根据作者的 [benchmark](http://rdfind.pauldreik.se/#g0.6),rdfind 比 duff 和 fslint 更快。 (14认同)
  • 我怀疑这个工具的性能更多地与算法本身有关,而与它是编译工具还是脚本无关。对于这种操作,磁盘几乎一直都是瓶颈。只要脚本化工具确保它们在以校验和燃烧 CPU 时正在进行异步 I/O 操作,它们的性能就应该与原生二进制文件一样好。 (5认同)
  • 请注意,某些版本的 `rdfind` 受到一个非常不方便的错误的影响:[无法创建硬链接时删除源文件](https://github.com/pauldreik/rdfind/issues/5)。 (3认同)
  • @db 我想知道有多少系统不到 1.5 年是最新的。我丢失了数据,其他人如果不检查他们的版本就会丢失。他们应该受到警告。 (3认同)

tan*_*nte 52

使用fdupes工具:

fdupes -r /path/to/folder为您提供目录中的重复项列表(-r 使其递归)。输出如下所示:


文件
名1文件名2

文件
名3
文件名4文件名5


文件名 1 和文件名 2 相同,文件名 3、文件名 4 和文件名 5 也相同。

  • 我只是尝试在 Ubuntu 和 Debian 上安装 fdupes_1.50-PR2-4,都没有 -L 标志。幸运的是,从 https://github.com/tobiasschulz/fdupes 构建非常简单。 (11认同)
  • `fdupes` 似乎只找到重复项,而不是用硬链接替换它们,因此不是 IMO 问题的答案。 (8认同)
  • 有一个类似的工具叫做 `jdupes`,它基于 `fdupes`,但它也可以用符号链接(`-l`)、硬链接(`-L`)替换重复文件或指示 btrfs 在文件系统级别对块进行重复数据删除(`-B`,如果你使用的是 btrfs)。 (5认同)
  • 尝试 `rdfind` - 类似于 `fdupes`,但速度更快,并且在 OS X 和 Cygwin 上也可用。 (3认同)

fsc*_*itt 42

http://cpansearch.perl.org/src/ANDK/Perl-Repository-APC-2.002/eg/trimtrees.pl有一个 perl 脚本,它完全符合您的要求:

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

  • 赞成这个,但在研究了更多之后,我知道我没有。`rdfind` 可通过所有主要平台(os x、linux、(cyg)win、solaris)的包管理器获得,并以惊人的本机速度运行。所以一定要看看下面的答案。 (14认同)
  • 对每个文件进行校验和,而不是仅存在至少一个具有相同大小的文件,效率低下(并且不必要地容易发生散列冲突)。 (7认同)
  • 这正是我所要求的。但是,我相信 ZFS 和 dedup 最终将成为可行的方法,因为我确实发现这些文件存在细微差别,因此只有少数文件可以进行硬链接。 (3认同)

wal*_*tor 28

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

  • 这似乎类似于 Fedora/RHEL/etc 上的原始“hardlink”。 (2认同)
  • `hardlink` 现在是许多 Linux 包系统(自 2014 年以来)中的原生二进制文件,并且速度非常快。对于 120 万个文件 (320GB),只需要 200 秒(链接大约 10% 的文件)。 (2认同)

小智 18

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

单击“合并”按钮:

截屏

  • -m 会将重复项硬链接在一起,-d 将删除除一个之外的所有内容,-t 将空运行,打印它会做什么 (4认同)

Wei*_*Yin 16

由于您的主要目标是节省磁盘空间,因此还有另一种解决方案:文件系统级别的重复数据删除(可能还有压缩)。与硬链接方案相比,不存在不慎影响其他链接文件的问题。

ZFS 从池版本 23 开始就进行了重复数据删除(块级,而不是文件级),并且很久以前就进行了压缩。如果您使用的是 linux,您可以尝试zfs-fuse,或者如果您使用 BSD,它是本机支持的。

  • ZFS dedup 是没有人的朋友。ZFS 建议每 1Tb 可用磁盘空间使用 1Gb ram,如果您尝试使用每 1Tb 可用磁盘空间少于 32Gb ram 的重复数据删除,那你就疯了。这意味着对于 1Tb 的镜像,如果您没有 32 Gb ram,您可能迟早会遇到内存炸弹情况,由于缺乏 ram 而导致机器停止运行。去过那里,做到了,仍在从创伤后应激障碍中恢复过来。 (18认同)
  • 为了避免在线重复数据删除(即检查每次写入)的过多 RAM 要求,`btrfs` 使用 _batch_ 或 _offline_ 重复数据删除(只要您认为有用/必要就运行它)https://btrfs.wiki.kernel.org/index .php/重复数据删除 (6认同)
  • 七年后更新:我最终确实转向了 ZFS 并尝试了重复数据删除——我发现它的 RAM 要求确实高得离谱。ZFS 快照的巧妙使用提供了我最终使用的解决方案。(复制一个用户的音乐、快照和克隆,使用 `rsync --inplace` 将第二个用户的音乐复制到克隆中,因此只存储更改的块) (6认同)

小智 8

如今在现代 Linux 上,有https://github.com/g2p/bedup可以在 btrfs 文件系统上进行重复数据删除,但是 1) 没有那么多的扫描开销,2) 之后文件很容易再次发生分歧。

  • https://btrfs.wiki.kernel.org/index.php/Deduplication 上列出了背景和更多信息(包括对“cp --reflink”的引用,另请参阅下文) (2认同)

Jul*_*ard 7

apt show hardlink
Run Code Online (Sandbox Code Playgroud)

Description: Hardlinks multiple copies of the same file Hardlink is a tool which detects multiple copies of the same file and replaces them with hardlinks.

I also used jdupes recently with success.


Ste*_*fan 6

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

Duff 是一个 Unix 命令行实用程序,用于快速查找给定文件集中的重复项。

只需运行:

duff -r target-folder
Run Code Online (Sandbox Code Playgroud)

要自动创建到这些文件的硬链接,您需要使用bash或其他一些脚本语言解析duff的输出。


Ski*_*rou 6

jdupes 已在评论中提到但值得自己回答,因为它可能在大多数发行版中可用并且运行速度非常快(它在大约一分钟内释放了 2.7?GB 的 98?%完整的 158?GB 分区(SSD 驱动器)) :

jdupes -rL /foo/bar
Run Code Online (Sandbox Code Playgroud)


joh*_*why 5

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

  • 文件名
  • 尺寸
  • md5 校验和
  • 字节内容

有什么方法可以做到这一点吗?看看duff,,,,等等。fdupesrmlintfslint

以下方法在commandlinefu.com上投票最多:查找重复文件(首先基于大小,然后是 MD5 哈希值)

是否可以将文件名比较添加为第一步,将大小比较添加为第二步?

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
Run Code Online (Sandbox Code Playgroud)

  • 在我的实践中,文件名是最不可靠的因素,并且我已将其从任何重复数据删除工作中完全删除。在活动系统上可以找到多少个“install.sh”文件?我无法计算保存文件并发生名称冲突的次数,并通过一些即时重命名来保存它。另一方面:不知道有多少次我在不同的日子从不同的来源下载了一些东西,却发现它们是具有不同名称的相同文件。(这也会破坏时间戳的可靠性。)1:大小,2:摘要,3:字节内容。 (4认同)
  • 我使用过“duff”、“fdupes”和“rmlint”,强烈建议读者查看[其中的第三个](http://rmlint.readthedocs.org/en/latest/)。它有一个优秀的选项集(和文档)。有了它,我能够避免与其他工具一起使用时需要进行的大量后期处理。 (3认同)