Anzeige:
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 15 von 17

Thema: Duplikate in Textdateien anzeigen. Oder ...

  1. #1
    Retardierter Benutzer
    Registriert seit
    May 2003
    Beiträge
    101

    Duplikate in Textdateien anzeigen. Oder ...

    Hi all,

    folgendes problem:

    ich habe eine textdatei, die ist alphabetisch sortiert,
    aber sie enthällt einige duplicates. Beispiel :

    apfel
    banane
    banane
    birne
    erdbeere
    erdbeere
    zitrone

    ich könnte ja mit sort -u die duplicate entfernen,
    jedoch ich will mir NUR die duplicate anzeigen lassen,
    d.h. ich will aus obiger datei folgende textdatei generieren:

    banane
    erdbeere

    ist das mit standard shell tools möglich ??



    Der eigentliche Hintergrund ist ein anderer:

    ich habe ein verzeichniss mit vielen unterverzeichnissen,
    in jedem unterverzeichniss sind teils unterschiedliche dateien drin
    jedoch manche dateien sind in mehreren unterverzeichnissen verteilt
    und identisch in filenamen und dateigrösse.
    Das ganze belegt (entpackt) 18 Gb (gepackt ca 10).
    Die duplicate sind so zahlreich, dass ich die komplette grösse
    auf die Hälfte reduzieren könnte, wenn ich jedes duplicat
    identifizieren könnte und je eine Kopie "echt" speichere
    und in allen anderen (unter-)ordnern "nur" einen symbolischen link
    zu der quelldatei erzeuge.
    Wenn ich das mache und obendrein gzippe oder bzippe, dann spare
    ich damit wirklich *VIEL* speicherplatz.

    Es handelt sich um 4083 Dateien, wobei die duplicate mitgezählt sind,
    welche ich mir per "ls -alR" in eine Textdatei gespeichert habe.

    Ich möchte die duplicate nicht "per Hand" herauslesen,
    daher de obige Frage, aber wenn jemand zum Hintergrund (unterer Teil)
    schon eine Lösung wüsste nehm ich die auch gerne an, weil dann
    erübrigt sich der "Textanzeige" part.

    Ich hoffe ich habe das Problem klar geschildert.

    Danke für eure *Hilfe* im Vorraus.

    Grüsse.

    Geändert von tobiasbeil (16.06.05 um 14:50 Uhr)

  2. #2
    Registrierter Benutzer
    Registriert seit
    Dec 2003
    Ort
    Dettenhausen
    Beiträge
    22.054
    nicht getestet, aber vielleicht so:
    Code:
    find . > alles.lst
    sort -u alles.lst > alles_u.lst
    
    diff --suppress-common-lines alles.lst alles_u.lst > dups.lst
    ... und mit der dups.lst dann weitermachen ;-)


    edit: evtl. muss man die alles.lst vorher auch noch sortieren, bevor man die Duplikate rausfiltert
    Geändert von marce (16.06.05 um 14:58 Uhr)
    Ich bin root - ich darf das.

  3. #3
    Registrierter Benutzer
    Registriert seit
    Jun 2005
    Beiträge
    10
    Oder kürzer:
    uniq -d FILE


    CU

  4. #4
    Registrierter Benutzer
    Registriert seit
    Dec 2003
    Ort
    Dettenhausen
    Beiträge
    22.054
    dass diese bescheuerten Linuxfrickler in ihrer massigen Freizeit nichts besseres zu tun haben als für jedes Problem, das noch nicht aufgetreten ist schon eine Lösung fertig zu haben ;-)

    naja, man kann nicht jedes Programm kennen ;-)
    Ich bin root - ich darf das.

  5. #5
    Retardierter Benutzer
    Registriert seit
    May 2003
    Beiträge
    101
    Zitat Zitat von marce
    dass diese bescheuerten Linuxfrickler in ihrer massigen Freizeit nichts besseres zu tun haben als für jedes Problem, das noch nicht aufgetreten ist schon eine Lösung fertig zu haben ;-)

    naja, man kann nicht jedes Programm kennen ;-)
    du sprichst mir aus der seele,
    aber gott sei dank gibt es diese linuxfreaks...

    zu oben:

    uniq -d hat geklappt, habe nun die liste wo nur die duplicates
    drin sind. als nächstes müsste ich einen "find . -name <xyz> >> <xyz>.dirs"
    ausführen, um für jedes duplikat zu erfahren, in welchen unterordnern
    es sich alles befindet.

    d.h. ich bräuchte als nächstes dem find sagen er soll sich
    statt dem platzhalter <xyz> den dateinamen der duplikate
    aus meine "dupicates.toc" liste holen,
    und das obendrein FÜR JEDES der 819 duplikate.

    jemand ne idee ??

  6. #6
    Registrierter Benutzer
    Registriert seit
    Jun 2005
    Beiträge
    10
    Das müsste funktionieren. Es geht bestimmt noch eleganter

    for i in $(cat duplicates.toc); do find -type f -iname $i >> duplicates.dirs ;done

    Das sucht dir für jeden Dateinamen in deiner duplicates.toc das Verzeichnis.
    -type f stellt dabei sicher, dass es sich um eine Datei handelt und keine Verzeichnisse mit gleichen Namen angezeigt werden.

  7. #7
    Retardierter Benutzer
    Registriert seit
    May 2003
    Beiträge
    101
    wenn ich das exakt so eingebe kommt "Parameter format not correct",
    wenn ichs nach dem ";" das done weglasse lande ich auf einer
    "seltsamen" kommandozeile.

  8. #8
    Registrierter Benutzer
    Registriert seit
    Dec 2003
    Ort
    Dettenhausen
    Beiträge
    22.054
    so - und nun kann ich endlich meine Standard-Antwort bringen:
    Code:
    man bash
    ... und viel Spaß beim lernen ;-)
    Ich bin root - ich darf das.

  9. #9
    Retardierter Benutzer
    Registriert seit
    May 2003
    Beiträge
    101
    Zitat Zitat von marce
    so - und nun kann ich endlich meine Standard-Antwort bringen:
    Code:
    man bash
    ... und viel Spaß beim lernen ;-)
    Code:
    bash-2.05b$ man bash
    /usr/local/lib/man.config: No such file or directory
    Warning: cannot open configuration file /usr/local/lib/man.config
    No manual entry for bash
    bash-2.05b$
    gut gekontert, wa ?

  10. #10
    Retardierter Benutzer
    Registriert seit
    May 2003
    Beiträge
    101
    also auf der aix-maschine bin ich folgendermassen weitergekommen:

    Code:
    for i in $(cat duplicates.toc);
    do find . -type f -iname $i >> duplicates.dirs;
    done
    Der punkt hat gefehlt.

    Nun habe ich sogar die Liste mit allen Verzeichnissen inklusive der
    Duplikatdateien und das ist schon mal richtig gut fürs weitere vorgehen.

    Ich werde mich nun weiter schlau machen und wenn das ergebniss ok ist,
    dann veröffentliche ich gleich hier in diesem Thread oder in einem Thread
    mit einem passenderem Titel das komplette script wie man duplicat dateien
    automatisch löschen und symbolisch verlinken kann.

    Wäre nett, wenn ihr Experten euch es dann aunschauen könntet und es
    "fehlertoleranter" machen könntet.
    (Abfrage auf Dateigrösse oder gar mit Hashing.)

    Einverstanden ?

    Bis dann....

    Geändert von tobiasbeil (17.06.05 um 10:37 Uhr)

  11. #11
    Registrierter Benutzer
    Registriert seit
    Dec 2003
    Ort
    Dettenhausen
    Beiträge
    22.054
    Zitat Zitat von tobiasbeil
    aix-maschine
    _das_ hättest Du vorher sagen können ;-)

    ist's ne richtige oder nur so ein aufgebohrter iPod? *duck*
    Ich bin root - ich darf das.

  12. #12
    Retardierter Benutzer
    Registriert seit
    May 2003
    Beiträge
    101
    is ne p520 4xpower power5 16gig ram.
    und das sind nur die "kleinen" maschinen wo wir unsere portierungen durchführen, quasi als "clients".

    unser p550 DB2 Server zum beispiel hat 8xPower4 und 64gig ram.

    *angeb*



    zu oben:

    das ist garnicht so einfach übrigends. ich weiss genau was geschehen muss,
    weiss aber nicht alle shell tricks und befehlsparameter,
    bitte helft mal weil ich will nur (ganz grob)...:

    1. ...in einem bestimmten verzeichniss, wo man duplicate vermutet ,z.Bsp
    "cd /maintenances" ...

    2. ...alle files auflisten...
    "ls -alR >> complete.toc"

    3. ...alphabetisch sortieren...
    "sort complete.toc >> sorted.toc"

    4. ...duplicate identifizieren...
    "uniq -d sorted.toc >> duplicates.toc"

    5. ...die verzeichnisse der duplicate aufspüren...
    "for i in $(cat duplicates.toc); do find . -type f -iname $i >> duplicates.dirs ;done"

    6. .. die "Quelldateien" identifizieren...
    "for i in $(cat duplicates.toc); do grep --nur-erstes-vorkommen-ausgeben $i duplicates.dirs >> sources.toc ;done"

    7. ...die "Nicht-Quelldateien/Duplicates/sym.Links" identifizieren...
    "for i in $(cat duplicates.toc); do grep -v --nur-erstes-vorkommen-ausgeben $i duplicates.dirs >> links.toc ;done" ???

    oder

    "for i in $(cat duplicates.toc); do grep --alles-ausser-erstes-vorkommen-ausgeben $i duplicates.dirs >> links.toc ;done" ???

    8. ...nur die verzeichnisse der "Duplicates" identifizieren, dazu muss ich die
    links.toc, welche in der form "./directory1/directory2/duplicate.file" vorliegt,
    so anpassen, dass der filename am ende der Zeile gelöscht wird und quasi nur
    "./directory1/directory2/" übrigbleibt...

    "for i in $(cat duplicates.toc); do grep --ausgeben-OHNE-suchstring $i links.toc >> links.dirs ;done" ???

    9. ...duplicate löschen...
    "for i in $(cat links.toc); do rm $i ;done"

    10. ...duplicate als "symbolische Links" wiederherstellen...
    "echo NICHT SO EINFACH"

    mein problem:
    schritt 10 wird aufwändig weil ich quasi für jedes duplicat die liste
    der verzeichniss in der es vorkommt irgendwie einzeln speichern müsste.
    zudem weiss ich für schritt 6 und 7 nicht wie man per grep oder sonstwie
    sich nur die zeile des ersten vorkommens ausgeben soll.

    ihr seht das problem ist zwar ogisch greifbar,
    aber mit der umsetzung hab ichs schwer.



    Edit: ach ja schritt 8 weiss ich auch net wie man zeilen nach einem
    suchbegriff sucht, aber so, dass der suchbegriff selbst nicht ausgegeben wird,
    oder von einem anderen programm "weggeschnitten" wird.

    EDIT2: und wieso überhaupt gibts es nicht schon ein "echtes" programm, welche mir die ganze script-arbeit abnimmt ?
    als echtes "binäres" programm ginge dies sowieso 10x schneller als ein shell-script.
    Geändert von tobiasbeil (17.06.05 um 12:10 Uhr)

  13. #13
    Retardierter Benutzer
    Registriert seit
    May 2003
    Beiträge
    101
    zu schritt 8 - 10:

    ist eigentlich folgendes möglich/erlaubt ?

    8. (verbessert) ...nur die verzeichnisse der "Duplicates" identifizieren, dazu muss ich die
    links.toc, welche in der form "./directory1/directory2/duplicate.file" vorliegt,
    so anpassen, dass der filename am ende der Zeile gelöscht wird und quasi nur
    "./directory1/directory2/" übrigbleibt...

    "for i in $(cat duplicates.toc); do grep --ausgeben-OHNE-suchstring $i links.toc >> $i.dupdirs ;done" ???

    Man beachte das "$i" als prefix des dateinames...
    später möchte ich dann per ...

    "for i in $(cat sources.toc); do
    for j in $(cat $i.dubdirs); do ln -s $i $j; done;
    done"

    ..jede Quelldatei "symbolisch verlinkt" in jedes verzeichniss, wo ein duplicat zu finden war, kopieren.


    Ist das korrekt so ???? geht das von der syntax her ?
    weil wenn ja, dann muss ich nur noch das mit dem grep herausfinden (schritt 6-8)
    Geändert von tobiasbeil (17.06.05 um 12:37 Uhr)

  14. #14
    Registrierter Benutzer
    Registriert seit
    Sep 2004
    Ort
    127.0.0.1
    Beiträge
    333
    Hi,

    wenn ich mich mal kurz einmischen darf ... diese bescheuerten Linuxfrickler ... haben für dieses Problem fdubes. Mehr Infos gibts hier.
    Aber bash Skripte schreiben macht natürlich auch Spaß

    Grüße
    Untergeher

    edit: Ich seh grad das Du 1. mit aix unterwegs bist und 2. dein Skript die zusätzliche Funktionalität mit der Ersetzung durch Links hat. Also: Weitermachen!
    Geändert von Der Untergeher (17.06.05 um 13:25 Uhr)

  15. #15
    Retardierter Benutzer
    Registriert seit
    May 2003
    Beiträge
    101
    so jetzt.

    meiner meinung nach bin ich fertig, hier der pseudo-code zum reviewen:

    Code:
    0. #!/bin/ksh
    1. ls -R >> complete.files
    2. sort complete.files >> sorted.files
    3. uniq -d sorted.files >> duplicates.files
    4. for i in $(cat duplicates.files);do find . -type f -name '$i' >> duplicates.toc;done
    5. for i in $(cat duplicates.files);do grep '$i' duplicates.toc | head -n 1 >> sources.toc;done
    6. for i in $(cat duplicates.files);do grep '$i' duplicates.toc >> $1.dpls;done
    7. for i in $(cat duplicates.files);do
    	for j in $(cat sources.toc);do grep -v '$j' $i.dpls >> $i.links;done;done
    8. for i in $(cat duplicates.files);do for j in $(cat $i.links);do rm $j;done;done
    9. for i in $(cat duplicates.files); do 
    		for j in $(cat $i.links); do
    			for h in $(cat sources.toc); do ln -s $h $j;done;
    		done;
    done
    10. exit 0


    dazu muss ich jetzt alles neu erklären:

    1. Eine Liste aller Dateinamen wird erstellt, daher die Endung .files.
    Diese symbolisiert Dateinamen.

    comlete.files sieht so aus:
    file1
    file2
    file4
    file3
    file1
    file1
    file2
    file6
    file4

    2. Obige Lite wird alphabetisch sortiert.

    sorted.files sieht so aus:
    file1
    file1
    file1
    file2
    file2
    file3
    file4
    file4
    file6

    3. Duplicate werden identifiziert und in duplicates.files geschrieben.

    duplicates.files sieht so aus:
    file1
    file2
    file4

    4. Es werden alle Duplicates indiziert mit relativ zum momentanen Verzeichniss qualifizierten Pfad und in duplicates.toc geschrieben.

    duplicates.toc sieht so aus:
    ./dir1/file1
    ./dir2/file1
    ./dir3/file1
    ./dir4/file2
    ./dir5/file2
    ./dir6/file4
    ./dir7/file4

    5. Aus obiger duplicates.toc Datei werden die Quelldateien ermittelt,
    in diesem Fall ist je das erste Vorkommen eines Duplicates die Quelldatei.
    Diese Quelldateien werden in sources.toc geschrieben.
    ".toc" steht immer für relativen Pfad mit Namen im Gegensatz zur Endung ".files", wo nur der Dateiname drin steht.

    sources.toc sieht so aus:
    ./dir1/file1
    ./dir4/file2
    ./dir6/file4

    6. Nun wird der Einfachheit halber für jedes Duplicat die komplette Liste erstellt und in <Dateiname>.dpls geschrieben,
    sie enthällt nicht nur das erste Vorkommen jedes Duplikats, dies wird später gebraucht und erleichtert das code-Lesen.
    Dabei entstehen soviele ".dpls" wie es Duplikate gibt.

    file1.dpls sieht so aus:
    ./dir1/file1
    ./dir2/file1
    ./dir3/file1

    7. Es werden anschliessend die Clone/nicht-Quelldateien ermittelt, welche später ja durch symbolische Links auf deren Quelldateien ersetzt werden sollen.
    Die ermittelten "Links" werden dann in der Form <Dateiname>.links gespeichert.
    Dabei entstehen soviele ".links" Dateien wie es aus Duplicate gibt.

    file1.links sieht so aus:
    ./dir2/file1
    ./dir3/file1

    file2.links sieht so aus:
    ./dir5/file2

    file4.links sieht so aus:
    ./dir7/file4

    8. Die Nicht-Quelldateien/Clone werden nun gelöscht, es gibt nun keine Duplicate mehr,
    jede Datei kommt nur 1 mal vor.

    Die einzelnen Befehle würden so aussehen, zum Beispiel für file1:
    rm ./dir2/file1
    rm ./dir3/file1
    usw...

    9. Im letzten Schritt werden für alle Duplicate alle symbolischen Links aus deren jeweiligen Quelldateien erzeugt, damit die "Illusion" entsteht sie wurden garnicht gelöscht, tatsächlich sind sie es physikalisch, da sie ja durch Dateien ersetzt wurden, welche schlicht auf eine Quelldatei "verweissen".

    Die einzelnen Befehle würden so aussehen, zum Beispiel für file1:
    ln -s ./dir1/file1 ./dir2/file1
    ln -s ./dir1/file1 ./dir3/file1
    usw...

    Ich würde mich EXTREM freuen wenn ihr diesen Code kommentieren würdet,
    zudem weiss ich nichtmal ob das syntaktisch korrekt ist so.

    Was sagt ihr dazu ?


    EDIT: ich habe einen Fehler entdeckt ich werde es gleich updaten.. die .links dateien werden fehlerhaft generiert, da muss noch ein for dazwischen geschoben werden,
    einen moment bitte....

    EDIT2: so jetzt stimmt der pseudo-Code.
    Bitte um reviewer oder gar tester...
    Geändert von tobiasbeil (17.06.05 um 15:57 Uhr)

Ähnliche Themen

  1. Versteckte Ordner und Dateien auf CD anzeigen
    Von D.Duck im Forum Linux Allgemein
    Antworten: 11
    Letzter Beitrag: 01.09.05, 03:46
  2. debian postfix "sasldb2 oder saslauthd"
    Von zini2001 im Forum Linux als Server
    Antworten: 1
    Letzter Beitrag: 14.03.05, 13:09
  3. Mandrake oder fli4l
    Von MR Action im Forum Linux Allgemein
    Antworten: 0
    Letzter Beitrag: 03.05.04, 14:40
  4. KCDemu kompilieren sclägt fehl
    Von dermartn im Forum Kompilieren von Kernel und Sourcen
    Antworten: 3
    Letzter Beitrag: 27.04.04, 16:38
  5. Map&Guide for Linux
    Von Torsten im Forum Anwendungen Allgemein, Software
    Antworten: 14
    Letzter Beitrag: 18.10.02, 14:14

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •