PeterLessing: 2 grosse formatierte Textdateien vergleichen

Hallo Leute,
ich habe ein wahrlich "grosses" Problem :-)

Ich habe 2 Textdateien, jeweils so um die 2 MB gross, die mir einen Zustand einer Datenbank anzeigen (Datenbak ist nicht direkt zugreifbar, sonst würde ich es machen).
Eine Datei ist von heute, die andere vom Vortag. Ich will nun diese beiden Dateien auf Änderungen bei den Objektattributen vergleichen und die veränderten Objektnamen in eine "Differenzdatei" ausgeben. Dabei geht es mir aber nur um die Objektnamen, nicht um die Attribute. Damit man es versteht, ein Beispiel:

prot.heute.txt:

[obj=111]
log=1
tag=9

[obj=222]
log=5
week=5
tag=8

[obj=333]
log=0
week="sense"
tag=2

... und so weiter. Die Datei vom Vortag prot.vortag.txt_

[obj=111]
log=0
tag=9

[obj=222]
log=5
week=5
tag=8

[obj=333]
log=0
week="nosense"
tag=2

...

Wie man hoffentlich jetzt am Beispiel sieht, sind die Attribute von obj=111 und obj=333 zumindest an einer Stelle unterschiedlich, also möchte ich diese beiden Objektnamen in der "Differenzdatei" haben. Also die Ausgabe sollte somit sein:

prot.diff.txt:

[obj=111]
[obj=333]

Wie kann ich so was am besten machen? Auch im Hinblick darauf, dass jede Textdatei 2 MB und mehr groß ist. Soll ich die zuerst zum Vergleich in ein Array (Hash?) einlesen, oder direkt beim Durchlaufen die Datei vergleichen? Performance ist dabei auch wichtig.

Ach ja, die Objekte sind sortiert, d.h. ich kann sicher sein, dass die Reihenfolge von [obj=...] immer gleich ist bei prot.heute.txt und prot.gestern.txt
Es gibt ca. 1000 verschiedene Attribute (also nicht erfassbar im Perl-Code)

Kann mir jemand vielleicht helfen? Ich verzweifel schon langsam...

Danke schon mal

Peter

  1. Hallo Peter,
    rufe doch mit deinem Perl-Script einfach die entsprechenden Systemtools auf.
    Windows: fc
    Unix: diff

    Grüße Oesi

    1. Hallo Peter,
      rufe doch mit deinem Perl-Script einfach die entsprechenden Systemtools auf.
      Windows: fc
      Unix: diff

      Grüße Oesi

      Hi Oesi,

      danke, aber die Idee hatte ich schon das mit diff zu machen. Nur gibt der mir vielleicht die Unterschiede von einzelnen Attribut-Zeilen aus, aber ich brauch ja dann den zugehörigen Objektnamen. Was im Attribut geändert wurde ist egal.
      Ich brauch nur dann den Objektnamen. und das kann diff nicht. Deshalb will ich ein Perl-Skript machen.

      Hast Du oder irgendwer dafür eine Idee?

      Grüße

      Peter

      1. hallo,

        Du kannst doch die Ausgabe von diff dann mit Perl noch so auswerten, wie Du willst.

        Grüße Oesi

        1. hallo,

          Du kannst doch die Ausgabe von diff dann mit Perl noch so auswerten, wie Du willst.

          Grüße Oesi

          Ja, theoretisch schon. Nur allerdings habe ich 3 verschiedene UNIX-Systeme, wo das Ding laufen soll: LINUX (suse), Solarise und Reliant. Und ich hab mir jetzt mal angesehen, dass der diff bei jedem UNIX die Ausgabe ein bisschen anders macht. Bei Reliant z. B. sieht man nicht die Objektnamen dazu. Ich muss dabei auch unterstellen, dass ein Objekt mehr als 100 verschiedene Attribute haben kann, d.h. wie konfiguriere ich die Ausgabe, damit dies sichergestellt ist.

          Kann ich dann auch immer auf
          <
          ---

          abfragen, um mir den Unterschied ansehen zu können?

          Von der Performance her kann ich mir schon vorstellen, dass das ganz gut funktionieren könnte. Aber ich darf keinen Unterschied (programmtechnisch) übersehen.

          Grüße

          Peter

          1. hallo,

            ich hätte da noch so eine Idee (quick and dirty)

            $/ =']';

            $x1 = <F1>;
            $x2 = <F2>;

            if ($x1 ne $x2){
            $x1 =~ /([obj=\d+])/o;
            print $1;
            }

            nur mal so als Ansatz.
            Habs nicht bis zu Ende durchgedacht(Schleifensteuerung, Fehlerbehandlung etc.).

            Grüße Oesi

            1. ich hätte da noch so eine Idee (quick and dirty)

              $/ =']';

              $x1 = <F1>;
              $x2 = <F2>;

              if ($x1 ne $x2){
              $x1 =~ /([obj=\d+])/o;
              print $1;
              }
              ...
              Grüße Oesi

              Erst mal danke Dir Oesi für die Mühe, die Du Dir machst.

              Dein obiger Vorschlag wäre ja ein direkter zeilenweiser Vergleich der Attribute in einem Objekt.
              Allerdings hätte ich nun ein Problem, nämlich kann es sein, dass ein Attribut in einer Datei reinkommt, das gestern noch gar nicht drin war oder umgekehrt. Auch bei den Objekten selbst kann dies genauso sein.
              Und schon haut der Match zeilenweise nicht hin, oder?
              Oder sollte in der Schleife, die noch außenrum kommt, sichergestellt sein, dass der Dateizeiger genau auf einem Objektnamen in [] Klammer steht?

              Auf jeden Fall schon mal vielen vielen Dank

              Peter

          2. Moin Peter,

            Von der Performance her kann ich mir schon vorstellen, dass das ganz gut funktionieren könnte. Aber ich darf keinen Unterschied (programmtechnisch) übersehen.

            Es gibt mehrere Perl Module, mit denen du das machen könntest. Z.B. Text::Diff. Z.B. dieses ist nur Perl, so dass du das Modul in ein Programm von dir einbauen könntest. Allerdings musst du die Liszenz beachten.

            Grüße Andres Freund

            --
            ss:) zu:) ls:} fo:) de:] va:) ch:| n4:& rl:° br:^ js:( ie:% fl:( mo:|
          3. Moin Peter,

            Ja, theoretisch schon. Nur allerdings habe ich 3 verschiedene UNIX-Systeme, wo das Ding laufen soll: LINUX (suse), Solarise und Reliant. Und ich hab mir jetzt mal angesehen, dass der diff bei jedem UNIX die Ausgabe ein bisschen anders macht.

            Du könntest, wie mir natürlich erst nach abschicken des letzen posts, die Option -u benutzen. Dann sollten alle Versionen/Implementationen von diff den gleichen output haben

            Grüße Andres Freund

            --
            ss:) zu:) ls:} fo:) de:] va:) ch:| n4:& rl:° br:^ js:( ie:% fl:( mo:|
  2. Ergänzung
    versuch mal das:

    diff -c -F /[obj=/ heute.txt vortag.txt

    Grüße Oesi

    1. versuch mal das:

      diff -c -F /[obj=/ heute.txt vortag.txt

      Grüße Oesi

      Die Shell kennt kein grosses -F nur ein kleines -f
      und das ergibt dann die Fehlermeldung, dass diese Option nicht mit -c kombiniert werden kann.

      Peter