Chr*_*own 114
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
Run Code Online (Sandbox Code Playgroud)
如果您的文件名包含换行符,这将中断。
ter*_*don 30
另一个好工具是fslint:
fslint 是一个工具集,用于查找文件系统的各种问题,包括重复文件和有问题的文件名等。
除了 GUI 之外,还可以使用单独的命令行工具来访问它们,可以在标准安装中更改或添加到 /usr/share/fslint/fslint 目录中的 $PATH。该目录中的每个命令都有一个 --help 选项,可以进一步详细说明其参数。
Run Code Online (Sandbox Code Playgroud)findup - find DUPlicate files
在基于 debian 的系统上,您可以使用以下命令安装它:
sudo apt-get install fslint
Run Code Online (Sandbox Code Playgroud)
如果您不想或无法安装第三方工具,也可以手动执行此操作。大多数此类程序的工作方式是计算文件校验和。具有相同 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
Run Code Online (Sandbox Code Playgroud)
示例输出(本例中的文件名相同,但在不同时也能工作):
$ 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
---
Run Code Online (Sandbox Code Playgroud)
这将是很多比已经提到的专用工具慢,但它会奏效。
如果您认为哈希函数(此处为 MD5)在您的域中是无冲突的:
find $target -type f -exec md5sum '{}' + | sort | uniq --all-repeated --check-chars=32 \
| cut --characters=35-
Run Code Online (Sandbox Code Playgroud)
想要将相同的文件名分组?编写一个简单的脚本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
Run Code Online (Sandbox Code Playgroud)
然后更改find命令以使用您的脚本:
chmod +x not_uniq.sh
find $target -type f -exec md5sum '{}' + | sort | not_uniq.sh
Run Code Online (Sandbox Code Playgroud)
这是基本思路。find如果您的文件名包含某些字符,您可能应该更改。(例如空格)
我想添加一个最近增强的 fdupes 分支jdupes,它有望比 fdupes更快,功能更丰富(例如大小过滤器):
jdupes . -rS -X size-:50m > myjdups.txt
Run Code Online (Sandbox Code Playgroud)
这将递归地查找当前目录中大于 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
Run Code Online (Sandbox Code Playgroud)