it-swarm.cn

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

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

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

146
Josh

http://cpansearch.Perl.org/src/ANDK/Perl-Repository-APC-2.002/eg/trimtrees.pl 处有一个Perl脚本,它确实可以满足您的要求:

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

42
fschmitt

rdfind 确实满足您的要求(并按照johny why列出的顺序)。使删除重复项成为可能,并用软链接或硬链接替换它们。与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)。

98
d-b

使用fdupes工具:

fdupes -r /path/to/folder为您提供目录中重复项的列表(-r使其递归)。输出看起来像这样:


文件名1
filename2

文件名3
filename4
filename5


其中filename1和filename2相同,并且filename3,filename4和filename5也相同。

51
tante
24
waltinator

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

点击“合并”按钮:

Screenshot

18
LJ Wobker

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

从池版本23开始,ZFS便已降级(块级,而不是文件级),而从很久以前开始压缩。如果使用的是Linux,则可以尝试 zfs-Fuse ,或者,如果您使用的是BSD,则本机支持。

14
Wei-Yin

在当今的现代Linux上, https://github.com/g2p/bedup 可以在btrfs文件系统上进行重复数据删除,但是1)扫描开销不大,2)文件可以轻松分散之后再来。

7
Matthew Bloch
aptitude show hardlink

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

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

6
Julien Palard

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

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

只需运行:

duff -r target-folder

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

6
Stefan

我已经使用了这里提到的许多用于Linux的硬链接工具。我也对Ubuntu上的ext4 fs感到困惑,并且一直在使用它的cp -l-s进行硬/软链接。但是最近在cp手册页中注意到了轻量级副本,这意味着要保留冗余磁盘空间直到一侧被修改:

   --reflink[=WHEN]
          control clone/CoW copies. See below

       When  --reflink[=always]  is specified, perform a lightweight copy, where the 
data blocks are copied only when modified.  If this is not possible the
       copy fails, or if --reflink=auto is specified, fall back to a standard copy.
4
Marcos

jdupes已在评论中提及,但应有自己的答案,因为它可能在大多数发行版中都可用,并且运行速度非常快(它仅释放了2.7 GB的98%完整158 GB分区(SSD驱动器),大约等一下) :

jdupes -rL /foo/bar
4
Skippy le Grand Gourou

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

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

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

以下方法是在 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
4
johny why

由于我不喜欢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

这将查找具有相同校验和的所有文件(无论它们是大,小还是已经进行了硬链接),并将它们硬链接在一起。

对于重复运行,可以使用其他查找标志(例如大小)和文件缓存(因此您不必每次都重做校验和)进行极大地优化。如果有人对更智能,更长的版本感兴趣,可以发布它。

NOTE:如前所述,只要文件不需要修改或在文件系统之间移动,硬链接就可以工作。

3
seren

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

1
islam

我制作了一个Perl脚本,它执行的操作与您所谈论的相似:

http://Pastebin.com/U7mFHZU7

基本上,它只是遍历目录,计算其中的文件的SHA1sum,将其哈希化并将匹配链接在一起。它在许多场合都派上用场。

1
amphetamachine

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

豪尔赫·桑帕约

1
Jorge H B Sampaio Jr

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

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

0
Amaroq Starwind

如果要进行硬链接,请注意该文件的权限。注意,所有者,组,模式,扩展属性,时间和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管理器。使用ZFS时不需要它。如果您想了解更多信息,请参阅文档。

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

0
Znik

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

dupeGuru Preferences Screenshot

documentation 所说

删除选项

这些选项影响重复删除的发生方式。大多数情况下,您无需启用任何一个。

链接已删除的文件:

删除的文件将替换为指向参考文件的链接。您可以选择用符号链接或硬链接替换它。 ...符号链接是文件路径的快捷方式。如果原始文件被删除或移动,则链接断开。硬链接是指向文件本身的链接。该链接与“真实”文件一样好。仅当删除到文件的所有硬链接时,文件本身才会被删除。

在OSX和Linux上,完全支持此功能,但在Windows下,则有点复杂。 Windows XP不支持它,但是Vista及更高版本支持它。但是,要使该功能正常工作,dupeGuru必须具有管理特权才能运行。