다음을 포함하는 파일 목록을 생성하고 싶습니다.
- 같은 이름
- 내용이 다릅니다
디렉터리(모든 하위 디렉터리 및 내용 포함)에 있습니다.
어떻게 하나요? 배쉬, 펄, 무엇이든 가능합니다.
따라서 이름과 내용이 동일한 두 개의 파일이 표시되어서는 안 됩니다.
답변1
업데이트: 스크립트의 오타를 수정했습니다. print $NF
다음으로 변경되었습니다 print $3
. 또한 몇 가지 사항을 정리하고 몇 가지 설명을 추가했습니다.
가설 파일이름포함되지 않음 \n
다음은 중단된 정렬 목록을 인쇄합니다(예:부분 제어 인터럽트) 고유 file name
, 고유 에 md5sum
해당 파일 경로 그룹을 표시합니다.
#!/bin/bash
# Choose which script to use for the final awk step
out_script=out_all
# Print all duplicated file names, even when md5sum is the same
out_all='{ if( p1 != $1 ) { print nl $1; print I $2 }
else if( p2 != $2 ) { print I $2 }
print I I $3; p1=$1; p2=$2; nl="\n" }
END { printf nl}'
# Print only duplicated file names which have multiple md5sums.
out_only='{ if( p1 != $1 ) { if( multi ) { print pend }
multi=0; pend=$1 "\n" I $2 "\n" }
else if( p2 != $2 ) { multi++; pend=pend I $2 "\n" }
pend=pend I I $3 "\n"; p1=$1; p2=$2 }
END { if( multi ) print pend }'
# The main pipeline
find "${1:-.}" -type f -name '*' | # awk for duplicate names
awk -F/ '{ if( name[$NF] ) { dname[$NF]++ }
name[$NF]=name[$NF] $0 "\n" }
END { for( d in dname ) { printf name[d] }
}' | # standard md5sum output
xargs -d'\n' md5sum | # " "==text, "*"==binary
sed 's/ [ *]/\x00/' | # prefix with file name
awk -F/ '{ print $3 "\x00" $0 }' | # sort by name. md5sum, path
sort | # awk to print result
awk -F"\x00" -v"I= " "${!out_script}"
출력 표시오직파일명은 와 같습니다많은 종류의 md5
에스
afile.html
53232474d80cf50b606069a821374a0a
./test/afile.html
./test/dir.svn/afile.html
6b1b4b5b7aa12cdbcc72a16215990417
./test/dir.svn/dir.show/afile.html
출력 표시모두같은 이름의 파일.
afile.html
53232474d80cf50b606069a821374a0a
./test/afile.html
./test/dir.svn/afile.html
6b1b4b5b7aa12cdbcc72a16215990417
./test/dir.svn/dir.show/afile.html
fi le.html
53232474d80cf50b606069a821374a0a
./test/dir.svn/dir.show/fi le.html
./test/dir.svn/dir.svn/fi le.html
file.html
53232474d80cf50b606069a821374a0a
./test/dir.show/dir.show/file.html
./test/dir.show/dir.svn/file.html
file.svn
53232474d80cf50b606069a821374a0a
./test/dir.show/dir.show/file.svn
./test/dir.show/dir.svn/file.svn
./test/dir.svn/dir.show/file.svn
./test/dir.svn/dir.svn/file.svn
file.txt
53232474d80cf50b606069a821374a0a
./test/dir.show/dir.show/file.txt
./test/dir.show/dir.svn/file.txt
./test/dir.svn/dir.show/file.txt
./test/dir.svn/dir.svn/file.txt
답변2
이것은 Perl 스크립트입니다. 검색하려는 트리 상단의 디렉터리에서 실행하세요. 스크립트는 find
및 에 의존 md5
하지만 후자는 또는 stdin에서 입력을 받아들이고 stdout에서 해시 값을 출력하는 다른 파일 해싱 프로그램 sha1
으로 대체될 수 있습니다.sum
use strict;
my %files;
my %nfiles;
my $HASHER = 'md5';
sub
print_array
{
for my $x (@_) {
print "$x\n";
}
}
open FINDOUTPUT, "find . -type f -print|" or die "find";
while (defined (my $line = <FINDOUTPUT>)) {
chomp $line;
my @segments = split /\//, $line;
my $shortname = pop @segments;
push @{ $files{$shortname} }, $line;
$nfiles{$shortname}++;
}
for my $shortname (keys %files) {
if ($nfiles{$shortname} < 2) {
print_array @{ $files{$shortname} };
next;
}
my %nhashes;
my %revhashes;
for my $file (@{ $files{$shortname} }) {
my $hash = `$HASHER < $file`;
$revhashes{$hash} = $file;
$nhashes{$hash}++;
}
for my $hash (keys %nhashes) {
if ($nhashes{$hash} < 2) {
my $file = $revhashes{$hash};
print "$file\n";
}
}
}
답변3
두푸 찾기이 도구는 이름이나 내용이 같은 파일을 나열하는 데도 도움이 됩니다.
답변4
내 한 줄 솔루션은 다음과 같습니다.
find . -type f -exec basename {} \; | sort | uniq -d | xargs -n 1 -I {name} sh -c 'echo {name}; find . -type f -name {name} -exec md5sum {} \;; echo'
다음과 같은 결과 세트를 인쇄합니다. 여기서 파일은 파일 이름별로 그룹화되고 중복 경로 목록과 각 파일의 md5 합계를 제공합니다.
file1.pdf
1983af4bc5c5e3fff33fb87b59147e0e ./folder1/file1.pdf
6d028226d0a08745c1d2993043e0baba ./folder2/file1.pdf
5830a22229a843a0bcc70d8d59419f03 ./folder3/file1.pdf
51d1844aad6bfddc60e381090d504a71 ./folder4/file1.pdf
file2.pdf
bd2c5037621998abcf3d33eb826dbfa6 ./folder1/file2.pdf
bd2c5037621998abcf3d33eb826dbfa6 ./folder2/file2.pdf