#!/bin/bash
#
# findcmp dir ...
# Sucht in den angegebenen Dir's alle identen Files
# Wegen der Performance: Nur Files *gleicher Größe* inhaltlich vergleichen
#
# Lösungsidee:
# 1.) Wir brauchen einen temporären File (am Ende wieder löschen!)
#     Er soll die Namen aller Files enthalten,
#     die gleich groß wie der aktuell geprüfte File sind.
# 2.) Dazu müssen wir uns merken, wie groß die Files im Tmpfile sind
#     (am Anfang 0)
# 3.) Ermittle alle "echten" Files (keine Dir's, Symlinks usw.) mit Größe > 0  
#     in allen auf der Befehlszeile angegebenen Verzeichnissen,
#     gib deren Größe und deren Name aus
#     (find kennt -printf für formatierte Ausgabe bestimmter File-Attribute),
#     und sortiere diese Ausgabe nach Größe
# 4.) Pipe die sortierte Ausgabe in eine while-Schleife,
#     die zeilenweise *zwei* Variablen einliest (Größe und Name),
#     bis das Einlesen fehlschlägt (d.h. bis alles gelesen ist)
# 5.) Vergleiche die gelesene Größe
#     mit der Größe der im Tmpfile gespeicherten Filenamen
# 6.) Wenn die Größe verschieden ist:
#     - Speichere den aktuellen Namen *statt* allen bisherigen Namen im Tmpfile
#     - Merk dir seine Größe als die neue Größe der Files im Tmpfile
# 7.) Wenn die Größe gleich ist:
#     - Mach eine weitere Schleife über alle Filenamen im Tmpfile
#       (dafür kann man while mit read sowie einer Eingabe-Umleitung ins while
#       oder eine for-Schleife verwenden)
#     - Vergleiche jeden File binär (nicht als Text) mit dem aktuellen File
#       (Befehl "cmp")
#     - Gib bei Gleichheit eine Meldung mit beiden Filenamen aus
#     - Füge den aktuellen File nach der Schleife zum Tmpfile dazu
#
# Alternative Lösung mit for als innere Schleife
# (funktioniert nicht bei Filenamen mit Zwischenräumen und bei zu vielen Files)

tmpfile=$(mktemp)
# Größe des zuletzt gelesenen Files
prevsize=0

# -size +0 ... nur Files mit Größe größer 0
find "$@" -type f -size +0 -printf "%s %p\n" | sort -n |
# die while-Schleife und damit das read bekommen ihren Input aus der Pipe!
while read size name
do
    if [ "$size" = "$prevsize" ]
    then
        # Aktuellen File mit aller bisherigen Files gleicher Größe vergleichen
        for prevname in $(cat $tmpfile)
        do
            if cmp -s "$name" "$prevname"
            then
                echo "\"$name\" und \"$prevname\" sind gleich" 
            fi
        done
        # Aktuellen Filenamen an den Tmpfile anhängen
        echo "$name" >> "$tmpfile"
    else
        # Neue Größe: Aktuellen Filenamen als ersten File im Tmpfile speichern
        echo "$name" > "$tmpfile"
        prevsize="$size"
    fi
done

rm "$tmpfile"
