是否有可能在我的磁盘上找到完全相同但文件名不同的重复文件?
答案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
如果您的文件名包含某些字符,您可能应该更改。 (例如空间)