Aynı ada ancak farklı içeriğe sahip dosyalar mı buldunuz?


9

Aşağıdakileri içeren dosyaların bir listesini oluşturmak istiyorum:

  • Aynı isim
  • Farklı içerik

(tüm alt dizinler ve içerik dahil).

Nasıl yapılır? Bash, perl, her şey yolunda.

Bu nedenle, aynı ada ve aynı içeriğe sahip iki dosya görünmemelidir.


Aynı ada sahip üç dosya ve üç dosyadan birinin aynı olduğunu varsayalım?
Kyle Jones

@KyleJones: "aynı ada sahip üç dosya ve üç dosyadan ikisi aynı"> Sonra bu dosya adı listeye eklenmelidir
Nicolas Raoul

Yanıtlar:


8

Güncelleme: komut bir yazım hatası düzeltildi: değişmiş print $NFiçin print $3; ayrıca işleri toparladı ve bazı yorumlar ekledi.

Dosya adlarının içermediği varsayılarak \n, aşağıdakiler benzersiz , benzersiz olan ve karşılık gelen dosya yolu grubunu gösteren ( bölüm denetimi sonları gibi ) sıralı bir liste yazdırılır . file namemd5sum

#!/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}"

Çıktı gösteren sadece dosya isimleri birden md5 s

afile.html
   53232474d80cf50b606069a821374a0a
      ./test/afile.html
      ./test/dir.svn/afile.html
   6b1b4b5b7aa12cdbcc72a16215990417
      ./test/dir.svn/dir.show/afile.html

Aynı ada sahip tüm dosyaları gösteren çıktı .

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

1

İşte bir Perl betiği. Aramak istediğiniz ağacın üstündeki dizinde çalıştırın. Senaryo bağlıdır findve md5ancak ikincisi ile değiştirilebilir sha1, sumveya stdin'i üzerinde girişini kabul eden ve stdout'ta bir karma verir başka bir dosya karma programı.

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";
        }
    }
}


1

Dosya adlarında yalnızca bir listesini görmek isteyenler için, burada ilgili bölümü olan Peter.O 'ın cevabı :

find "${1:-.}" -type f -name '*' | 
awk -F/ '{ if( name[$NF] ) { dname[$NF]++ }
       name[$NF]=name[$NF] $0 "\n" } 
 END { for( d in dname ) { printf name[d] "\n" } 

}'

fslint-guiTüm yinelenenleri temizlemek için komut dosyasından önce kullandığım için md5sums gerekmez .


benim mac bu aynı dosyaları aynı adı aynı içeriği gösterir
nightograph
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.