使用bash根据md5查找重复文件

时间:2013-10-23 20:43:46

标签: bash shell

我想编写一个关于bash的算法,它找到了重复的文件

如何添加尺寸选项?

7 个答案:

答案 0 :(得分:11)

不要重新发明轮子,使用正确的命令:

fdupes -r dir

请参阅http://code.google.com/p/fdupes/(在某些Linux发行版上打包)

答案 1 :(得分:10)

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

这就是你想要的方式。此代码首先根据大小定位重复,然后是MD5散列。请注意与您的问题相关的-size的使用。请享用。假设您要在当前目录中搜索。如果没有,请将find .更改为适合您要搜索的目录。

答案 2 :(得分:2)

find /path/to/folder1 /path/to/folder2 -type f -printf "%f %s\n" | sort | uniq -d

find命令在两个文件夹中查找文件,仅打印文件名(删除前导目录)和大小,排序并仅显示dupes。这确实假设文件名中没有换行符。

答案 3 :(得分:1)

通常我使用fdupes -r -S .。但是当我搜索较少量非常大的文件的副本时,fdupes需要很长时间才能完成,因为它会对整个文件执行完整的校验和(我猜)。

我通过仅比较前1兆字节来避免这种情况。它不是超级安全的,如果你想100%肯定,你必须检查它是否真的重复。但两个不同视频(我的情况)具有相同的第一兆字节但不同的进一步内容的机会相当具有理论性。

所以我写了这个脚本。 它加速的另一个技巧是它将特定路径的结果哈希存储到文件中。我依赖文件不会改变的事实。

我将此代码粘贴到控制台而不是运行它 - 为此,它需要更多的工作,但是你有这个想法:

find -type f -size +3M -print0 | while IFS= read -r -d '' i; do
  echo -n '.'
  if grep -q "$i" md5-partial.txt; then
    echo -n ':'; #-e "\n$i  ---- Already counted, skipping.";
    continue;
  fi
  MD5=`dd bs=1M count=1 if="$i" status=none | md5sum`
  MD5=`echo $MD5 | cut -d' ' -f1`
  if grep "$MD5" md5-partial.txt; then echo -e "Duplicate: $i"; fi
  echo $MD5 $i >> md5-partial.txt
done
fi

## Show the duplicates
#sort md5-partial.txt | uniq  --check-chars=32 -d -c | sort -b -n | cut -c 9-40 | xargs -I '{}' sh -c "grep '{}'  md5-partial.txt && echo"

另一个用于确定最大重复文件的bash片段:

## Show wasted space
if [ false ] ; then
sort md5-partial.txt | uniq  --check-chars=32 -d -c | while IFS= read -r -d '' LINE; do
  HASH=`echo $LINE | cut -c 9-40`;
  PATH=`echo $LINE | cut -c 41-`;
  ls -l '$PATH' | cud -c 26-34
done

这两个脚本都有很大的改进空间,可以随时提供 - here is the gist:)

答案 4 :(得分:0)

您可以使用cmp来比较文件大小:

#!/bin/bash

folder1="$1"
folder2="$2"
log=~/log.txt

for i in "$folder1"/*; do
    filename="${i%.*}"
    cmp --silent "$folder1/$filename" "$folder2/$filename" && echo "$filename" >> "$log"
done

答案 5 :(得分:0)

这可能是一个较晚的答案,但是现在fdupes的替代方法要快得多。

  1. fslint/findup
  2. jdupes,应该可以更快地替代fdupes

我有时间做一个小测试。对于标准(8 vCPU / 30G)Google虚拟机上具有54,000个文件,总大小为17G的文件夹:

  • fdupes耗时200万47.082秒
  • findup耗时13.556s
  • jdupes花费0.165秒

但是,我的经验是,如果文件夹太大,则时间可能会变得很长(几小时,如果不是几天),因为成对比较(或充其量只能进行排序)和非常耗费内存的操作很快会变得非常缓慢。在整个磁盘上运行这样的任务是不可能的。

答案 6 :(得分:0)

如果由于某种原因不能使用* dupes并且文件数量非常高,则sort+uniq的性能将不佳。在这种情况下,您可以使用以下方式:

find . -not -empty -type f -printf "%012s" -exec md5sum {} \; | awk 'x[substr($0, 1, 44)]++'

find将为每个文件创建一行,文件大小以字节为单位(我使用12个位置,但YMMV)和文件的md5哈希(加上名称)。
awk将过滤结果,而无需事先进行排序。 44代表12(代表文件大小)+ 32(哈希长度)。如果您需要有关awk程序的一些说明,可以查看基础知识here