递归查找同一目录中已确认重复的文件

递归查找同一目录中已确认重复的文件

假设我有以下目录结构:

root
 |-- dirA
     |-- file.jpg
     |-- file-001.jpg <-- dup
     |-- file2.jpg
     |-- file3.jpg
 |-- dirB
     |-- fileA.jpg
     |-- fileA_ios.jpg <-- dup
     |-- fileB.jpg
     |-- fileC.jpg
 |-- dirC
     |-- fileX.jpg
     |-- fileX_ios.jpg <-- dup
     |-- fileX-001.jpg <-- dup
     |-- fileY.jpg
     |-- fileZ.jpg

因此,给定一个根文件夹,如何递归地找到具有相同名称(仅后缀不同)的重复项?

名称可以是任何字符串,但不一定是file....后缀可以是 001、002、003 等。但可以安全地假设将有一个 3 位数字模式和_ios字面意义(用于正则表达式匹配)。

我的linux foo 不是很好。

答案1

它有点长,但它是一个命令行。它查看文件的内容并使用加密哈希 ( md5sum) 进行比较。

find . -type f -exec md5sum {} + | sort | sed 's/  */!/1' | awk -F\| 'BEGIN{first=1}{if($1==lastid){if(first){first=0;print lastid, lastfile}print$1, $2} else first=1; lastid=$1;lastfile=$2}'

正如我所说,这有点长......

find针对md5sum当前目录树中的所有文件运行。然后输出是sort通过 md5 哈希进行的。由于文件名中可能存在空格,因此sed将第一个字段分隔符(两个空格)更改为垂直管道(不太可能出现在文件名中)。

最后一个awk命令跟踪三个变量:lastid= 前一个条目的 md5 哈希值,lastfile= 前一个条目的文件名,以及first= 第一次看到的lastid。

输出包括哈希值,因此您可以看到哪些文件彼此重复。

这并不表明文件是否是硬链接(相同的 inode,不同的名称);它只会比较内容。

更新:仅根据文件的基本名称进行更正。

find . -type f -print | sed 's!.*/\(.*\)\.[^.]*$!\1|&!' | awk -F\| '{i=indices[$1]++;found[$1,i]=$2}END{for(bname in indices){if(indices[bname]>1){for(i=0;i<indices[bname];i++){print found[bname,i]}}}}'

这里,find仅列出文件名,sed采用路径名的基本名称部分,并创建一个包含基本名称和完整路径名的两个字段表。然后awk创建一个所见路径名的表(“找到”),按基本名称和项目编号进行索引; “indices”数组跟踪有多少个基本名称已被看到。然后“END”子句打印出找到的任何重复的基本名称。

答案2

您可能需要考虑专门用于搜索重复文件的程序,而不是依赖于名称,例如fdupesfslint

答案3

创建目录结构

mkdir dir{A,B,C}
touch dirA/file{,-001,2,3}.jpg
touch dirB/file{A,A_ios,B,C}.jpg
touch dirC/file{X,X_ios,X-001,Y,Z}.jpg

显示多个重复文件

find . -name '*.jpg' -type f |sed 's/\(.*\/\(file.\).*\(.jpg\)\)/\2/' |sort |uniq -c|grep -v 1 

退货

2 文件A
3 文件X

相关内容