如何删除文件的所有重复硬链接?

如何删除文件的所有重复硬链接?

我有一个由 创建的目录树rsnapshot,其中包含同一目录结构的多个快照,所有相同的文件都被硬链接替换。

我想删除所有这些硬链接重复项,并只保留每个文件的一个副本(这样我以后就可以将所有文件移动到排序的存档中,而不必两次触摸相同的文件)。

有没有一个工具可以做到这一点?
到目前为止,我只找到了可以查找重复项的工具创造硬链接来替换它们......
我想我可以列出所有文件及其索引节点号并实现重复数据删除和删除自己,但我不想在这里重新发明轮子。

答案1

最后,基于以下内容,手动执行此操作并不难史蒂芬的类xenoid的提示和一些先前的经验find
我必须调整一些命令才能与 FreeBSD 的非 GNU 工具一起使用 - GNUfind-printf可以替换 的选项-exec stat,但 FreeBSDfind没有。

# create a list of "<inode number> <tab> <full file path>"
find rsnapshots -type f -links +1 -exec stat -f '%i%t%R' {} + > inodes.txt

# sort the list by inode number (to have consecutive blocks of duplicate files)
sort -n inodes.txt > inodes.sorted.txt

# remove the first file from each block (we want to keep one link per inode)
awk -F'\t' 'BEGIN {lastinode = 0} {inode = 0+$1; if (inode == lastinode) {print $2}; lastinode = inode}' inodes.sorted.txt > inodes.to-delete.txt

# delete duplicates (watch out for special characters in the filename, and possibly adjust the read command and double quotes accordingly)
cat inodes.to-delete.txt | while read line; do rm -f "$line"; done

答案2

要查找具有多个链接的索引节点:

 find . -exec stat -c '%i' {} \; | sort -n | uniq -d

然后你可以迭代该列表

 find -inum {inode_number}

列出共享该 inode 的文件。删除哪一个取决于您。

答案3

如果您知道所有文件仅在单个目录层次结构中具有硬链接,您可以简单地执行以下操作

find inputdir -type f -links +1 -exec rm {} \;

这样做的原因是,rm {} \;立即删除一个文件,stat()返回计数超过 1。因此,同一 inode 的其他部分的硬链接计数将减 1,如果该文件是唯一的副本,则rm当 find 对最后一个文件运行时,将不会对该文件运行stat()

请注意,如果任何文件在外部有硬链接副本inputdir此命令之外具有硬链接副本将删除所有副本在等级制度内inputdir

答案4

林特将查找并删除重复项,包括硬链接。目前没有删除选项仅有的硬链接。删除是通过自动生成的 shell 脚本完成的,因此您可以在删除之前查看该脚本。

一般来说,在硬链接模式下使用重复文件检测器(例如 fdupes -H)时要小心,因为它们有时会错误地将文件识别为自己的重复文件(请参阅“路径加倍”讨论)这里)。

相关内容