查找重复文件

查找重复文件

是否有可能在我的磁盘上找到完全相同但文件名不同的重复文件?

答案1

fdupes可以做到这一点。从man fdupes

在给定路径中搜索重复文件。通过比较文件大小和 MD5 签名,然后逐字节比较来找到此类文件。

在 Debian 或 Ubuntu 中,您可以使用apt-get install fdupes.在Fedora/Red Hat/CentOS中,您可以使用yum install fdupes.在 Arch Linux 上,您可以使用pacman -S fdupes,在 Gentoo 上,可以使用emerge fdupes.

要运行从文件系统根目录开始的检查(这可能会花费大量时间和内存),请使用类似fdupes -r /.

正如评论中所要求的,您可以通过执行以下操作来获得最大的重复项:

fdupes -r . | {
    while IFS= read -r file; do
        [[ $file ]] && du "$file"
    done
} | sort -n

如果您的文件名包含换行符,这将会中断。

答案2

另一个好工具是fslint:

fslint 是一个工具集,用于查找文件系统的各种问题,包括重复文件和有问题的文件名等。

除了 GUI 之外,还提供单独的命令行工具,要访问它们,可以更改为标准安装上的 /usr/share/fslint/fslint 目录,或将其添加到 $PATH。该目录中的每个命令都有一个 --help 选项,可进一步详细说明其参数。

   findup - find DUPlicate files

在基于 Debian 的系统上,您可以使用以下命令安装它:

sudo apt-get install fslint

如果您不想或无法安装第三方工具,也可以手动执行此操作。大多数此类程序的工作方式是通过计算文件校验和。具有相同 md5sum 的文件几乎肯定包含完全相同的数据。所以,你可以这样做:

find / -type f -exec md5sum {} \; > md5sums
awk '{print $1}' md5sums | sort | uniq -d > dupes
while read -r d; do echo "---"; grep -- "$d" md5sums | cut -d ' ' -f 2-; done < dupes 

示例输出(本例中的文件名相同,但不同时也可以工作):

$ while read -r d; do echo "---"; grep -- "$d" md5sums | cut -d ' ' -f 2-; done < dupes 
---
 /usr/src/linux-headers-3.2.0-3-common/include/linux/if_bonding.h
 /usr/src/linux-headers-3.2.0-4-common/include/linux/if_bonding.h
---
 /usr/src/linux-headers-3.2.0-3-common/include/linux/route.h
 /usr/src/linux-headers-3.2.0-4-common/include/linux/route.h
---
 /usr/src/linux-headers-3.2.0-3-common/include/drm/Kbuild
 /usr/src/linux-headers-3.2.0-4-common/include/drm/Kbuild
---

这会是很多比已经提到的专用工具慢,但它会起作用。

答案3

我想添加一个最近增强的 fdupes 分支,杜佩斯,这有望成为快点比 fdupes 功能更丰富(例如尺寸过滤器):

jdupes . -rS -X size-:50m > myjdups.txt

这将递归地查找当前目录中大于 50MB 的重复文件,并将结果列表输出到 myjdups.txt 中。

请注意,输出未按大小排序,并且由于它似乎不是内置的,因此我改编了上面的 @Chris_Down 答案来实现此目的:

jdupes -r . -X size-:50m | {
    while IFS= read -r file; do
        [[ $file ]] && du "$file"
    done
} | sort -n > myjdups_sorted.txt

答案4

如果您认为哈希函数(此处为 MD5)在您的域上是无冲突的:

find $target -type f -exec md5sum '{}' + | sort | uniq --all-repeated --check-chars=32 \
 | cut --characters=35-

想要将相同的文件名分组吗?编写一个简单的脚本not_uniq.sh来格式化输出:

#!/bin/bash

last_checksum=0
while read line; do
    checksum=${line:0:32}
    filename=${line:34}
    if [ $checksum == $last_checksum ]; then
        if [ ${last_filename:-0} != '0' ]; then
            echo $last_filename
            unset last_filename
        fi
        echo $filename
    else
        if [ ${last_filename:-0} == '0' ]; then
            echo "======="
        fi
        last_filename=$filename
    fi

    last_checksum=$checksum
done

然后更改find命令以使用您的脚本:

chmod +x not_uniq.sh
find $target -type f -exec md5sum '{}' + | sort | not_uniq.sh

这是基本的想法。find如果您的文件名包含某些字符,您可能应该更改。 (例如空间)

相关内容