2017-03-09 3 views
0

Ich bin auf der Suche nach einer Möglichkeit zu finden, ob ein Verzeichnis aus dem aktuellen Verzeichnis alle doppelten Verzeichnisse hat, rekursiv.
heißtrekursiv finden Verzeichnisse mit identischen Sets von Dateinamen

/user/guy/textfile1.txt 
/user/guy/textfile2.txt 
/user/guy/textfile3.txt 
/user/girl/textfile1.txt 
/user/girl/textfile2.txt 
/user/girl/textfile3.txt 
/user/fella/textfile1.txt 
/user/fella/textfile2.txt 
/user/fella/textfile3.txt 
/user/fella/textfile4.txt 
/user/rudiger/rudy/textfile1.txt 
/user/rudiger/rudy/textfile2.txt 
/user/rudiger/rudy/textfile3.txt 
/user/julian/rudy/textfile1.txt 
/user/julian/rudy/textfile2.txt 
/user/julian/rudy/textfile3.txt 

/Mädchen und/Typ/rudy würde doppelte Verzeichnisse sein und so würde/julian und rudiger. Wir würden auch prüfen, ob eine andere Datei dieselben Dateien/Verzeichnisse wie "Benutzer" enthält. Da wir das Skript von "user" als aktuelles Verzeichnis ausführen, wollen wir das aktuelle Verzeichnis auch auf Duplikate in der Zeile überprüfen.

Mein aktueller Code, der funktioniert ... aber es ist nicht rekursiv, was ein Problem ist.

for d in */ ; do 
    for d2 in */ ; do 
    if [ "$d" != "$d2" ] ; then 
     string1="$(ls "$d2")" 
     string2="$(ls "$d")" 
     if [ "$string1" == "$string2" ] ; then 
      echo "The directories $d and $d2 are the same" 
     fi 
    fi 
    done 
done 
+0

Generieren eines Hash des Inhalts jedes Verzeichnisses. Sortieren Sie diese Liste nach Hash. Zwei Zeilen nebeneinander mit dem gleichen Hash == zwei Verzeichnisse mit gleichnamigen Einträgen. –

+0

... Sie wollen diesen Vergleich wirklich nicht paarweise machen - das bedeutet, dass Sie eine exponentielle Laufzeit haben, wenn die Anzahl der Verzeichnisse wächst. –

Antwort

2
#!/usr/bin/env bash 
#    ^^^^- must be bash, not /bin/sh, and version 4.0 or newer. 

# associative array mapping hash to first directory seen w/ same 
declare -A hashes=() 

# sha256sum requiring only openssl, vs GNU coreutils 
sha256sum() { openssl dgst -sha256 -r | sed -e '[email protected][[:space:]].*@@'; } 

while IFS= read -r -d '' dirname; do 
    hash=$(cd "$dirname" && printf '%s\0' * | sha256sum) 
    if [[ ${hashes[$hash]} ]]; then 
    echo "COLLISION: Directory $dirname has same filenames as ${hashes[$hash]}" 
    else 
    hashes[$hash]=$dirname 
    fi 
done < <(find . -type d -print0) 
Verwandte Themen