Intelligente "Subtraktion" einer Textdatei von einer anderen

425
Vi.

Beispiel: Die Anwendung generiert eine große Textprotokolldatei Amit vielen verschiedenen Meldungen. Es erzeugt eine ähnlich große Protokolldatei, Bwenn es nicht ordnungsgemäß funktioniert.

Ich möchte sehen, welche Nachrichten in der Datei Bgrundsätzlich neu sind, dh alles ausfiltern A.

Trivialer Prototyp ist:

  1. Sortieren | uniq beide Dateien
  2. Dateien verbinden
  3. sortieren | uniq -c
  4. grep -v "^ 2"

Dies erzeugt einen symmetrischen Unterschied und ist unpraktisch. Wie geht es besser? (einschließlich nicht symmetrischer Unterschiede und Erhalt der Nachrichtenreihenfolge in B)

Das Programm sollte zuerst analysieren Aund lernen, welche Nachrichten allgemein sind, und dann das Anzeigen Bmit den Nachrichten analysieren, die Aufmerksamkeit erfordern.

Idealerweise sollte es Dinge wie Zeitstempel, Zeilennummern oder andere unbeständige Dinge automatisch ignorieren.

Beispiel. EIN:

0:00:00.234 Received buffer 0x324234 0:00:00.237 Processeed buffer 0x324234 0:00:00.238 Send buffer 0x324255 0:00:03.334 Received buffer 0x324255 0:00:03.337 Processeed buffer 0x324255 0:00:03.339 Send buffer 0x324255 0:00:05.171 Received buffer 0x32421A 0:00:05.173 Processeed buffer 0x32421A 0:00:05.178 Send buffer 0x32421A 

B:

0:00:00.134 Received buffer 0x324111 0:00:00.137 Processeed buffer 0x324111 0:00:00.138 Send buffer 0x324111 0:00:03.334 Received buffer 0x324222 0:00:03.337 Processeed buffer 0x324222 0:00:03.338 Error processing buffer 0x324222  0:00:03.339 Send buffer 0x3242222 0:00:05.271 Received buffer 0x3242FA 0:00:05.273 Processeed buffer 0x3242FA 0:00:05.278 Send buffer 0x3242FA 0:00:07.280 Send buffer 0x3242FA failed 

Ergebnis:

0:00:03.338 Error processing buffer 0x324222  0:00:07.280 Send buffer 0x3242FA failed 

Eine Möglichkeit, es zu lösen, kann so etwas sein:

  1. Split jede Zeile in logischen Einheiten: 0:00:00.134 Received buffer 0x324111, 0:00:00.134, Received, buffer, 0x324111, 324111, Received buffer, \d:\d\d:\d\d\.\d\d\d, \d+:\d+:\d+.\d+, 0x[0-9A-F], ... Es soll einzelne Worte finden, einfache Muster in Zahlen, gemeinsame Layouts (zB „einig Datum als Text als Zahl als Text als end_of_line“), auch Handle Kombinationen von oben. Da es keine einfache Aufgabe ist, müssen Benutzerunterstützung (Hinzufügen von regulären Ausdrücken mit explizitem "Ignorieren von", "machen den Hauptfaktor", "nicht in Teile aufteilen", "als Datum / Nummer berücksichtigen") für Reihenfolge / Menge sorgen für solche Nachrichten "Regeln" sollte unterstützt werden (aber nicht erforderlich).
  2. Suchen Sie sich wiederkehrende Einheiten und "kategorisieren" Sie Zeilen, filtern Sie zu unbeständige Dinge wie Zeitstempel, Adressen oder Zeilennummern.
  3. Analysieren Sie die zweite Datei, finden Sie Dinge, die neue logische Einheiten haben (einmalig oder wiederkehrend), oder alles, was das System, das sich an die erste Datei gewöhnt hat, "überraschen" wird.

Beispiel dafür, wie Sie etwas manuell ausführen:

$ cat A | head -n 1 0:00:00.234 Received buffer 0x324234  $ cat A | egrep -v "Received buffer" | head -n 1 0:00:00.237 Processeed buffer 0x324234  $ cat A | egrep -v "Received buffer|Processeed buffer" | head -n 1 0:00:00.238 Send buffer 0x324255  $ cat A | egrep -v "Received buffer|Processeed buffer|Send buffer" | head -n 1  $ cat B | egrep -v "Received buffer|Processeed buffer|Send buffer" 0:00:03.338 Error processing buffer 0x324222  0:00:07.280 Send buffer 0x3242FA failed 

Dies ist eine langweilige Sache (es gibt viele Nachrichtentypen); Ich kann auch versehentlich ein zu breites Muster hinzufügen. Es kann auch nicht mit komplizierten Dingen wie Wechselbeziehungen zwischen Nachrichten umgehen.

Ich weiß, dass es KI-bezogen ist. Möglicherweise gibt es bereits entwickelte Werkzeuge?

3
Korrigieren Sie mich, wenn ich falsch liege, aber sollen diese Fragen nicht bei SO gepostet werden ??? Avis vor 13 Jahren 0
@Avis, ich denke Fragen wie "welches Programm soll ich machen ...." ist SU. Natürlich ist ein solches Programm auch für Benutzer von SO und SF nützlich. Vi. vor 13 Jahren 0
@Vi: Sie scheinen sich auf eine Programmierlösung zu konzentrieren, anstatt zu versuchen, ein hypothetisches geeignetes Programm zu finden. Nach Design-Tipps zu SO zu fragen, scheint angemessen. Gilles vor 13 Jahren 0
@Gilles, Meine Fragen beginnen oft mit "welches Programm soll ich verwenden, um dies und das zu tun" und endet mit einem Skript, das ich (oder ein anderer Benutzer) geschrieben habe. Ich weiß nicht, ob solche Dinge zu SO migriert werden sollten. / * Fragen Sie bei Meta * / Vi. vor 13 Jahren 0

3 Antworten auf die Frage

0
b0fh

diff(und die verschiedenen Optionen) zeigen Ihnen beide Möglichkeiten und behalten die Reihenfolge der Nachrichten bei. Es werden jedoch keine Duplikate von Unterschieden entfernt (für die Sie sich uniqspäter bewerben können ) oder sich mit abweichender Reihenfolge befassen. Ist das gut genug?

Dateien sind nicht so ähnlich. Es gibt viele Dinge wie Zeitstempel, unterschiedliche Reihenfolge und Anzahl ähnlicher Meldungen. Vi. vor 13 Jahren 0
0
Gilles

Verwenden Sie diff(im normalen Ausgabemodus, dh kein -coder -u). Die neuen Zeilen werden mit vorangestellt >.

diff A B | sed -ne 's/> //p' 

Wenn die Protokolle Zeitstempel enthalten, müssen Sie sie zuerst entfernen.

Manchmal ist es schöner, die neuen / geänderten Bits im Kontext zu sehen, wobei der Unterschied hervorgehoben wird und die Navigation zwischen verschiedenen Abschnitten erfolgt. Emacs hat dafür eine schöne Schnittstelle (Menü Extras | Vergleichen, M-x ediff-files). Es gibt auch viele eigenständige Tools (oft mit "diff" oder "compare" im Namen).

Wenn Sie an der Reihenfolge der Zeilen nicht interessiert sind, commwäre das Sortieren der beiden Dateien nach und nach einfacher und angenehmer als der Prozess, den Sie in Ihrer Frage angeben.

Funktioniert `diff` wirklich, wenn Dateien keine großen gemeinsamen Teile haben, nur _similar_, z. B. dieselben Nachrichtentypen (außer einigen zusätzlichen Nachrichten in` B`)? Dateien sind sehr groß und es gibt viele verschiedene Nachrichtentypen. Die Anwendung selbst verfügt über Timer und misst deren Leistung und ist vom Server (der auch einen Timer besitzt) abhängig. PS Es ist ein ausführliches Debug-Protokoll von gstreamer. Vi. vor 13 Jahren 0
@Vi: Nein, für 'diff' muss der gemeinsame Teil mit Ausnahme von Whitespace identisch sein. Das generelle Problem beim Vergleich solcher Anwendungsspuren kann sehr schwierig sein. Angesichts der Beispielausgabe, die Sie jetzt gepostet haben, sieht das Ignorieren von Zeitstempeln in Ordnung aus, aber die Puffernummern vermitteln Informationen, die Sie nicht verlieren möchten. Enthalten A und B identische Sequenzen von Puffersenden und -sendern (mit unterschiedlichen Nummern und Erfolg / Misserfolg), oder bricht die Korrespondenz schnell zusammen? Gilles vor 13 Jahren 0
Ich muss wissen, welche Botschaften in `B` grundsätzlich neu sind. / * hat die jeweilige Aufgabe bereits von Hand erledigt, indem sie sehr lange `cat A | egrep -b 'msg1 | msg2 | msg3 | ... | msgN'`-Zeile und gibt sie auf `b` * / aus. Ich denke, es sollte etwas AI-unterstützt sein, wie Auto-Kategorisierungs- oder Keyword-Extractor-Dinge. Vi. vor 13 Jahren 0
s / egrep -b / egrep -v / Vi. vor 13 Jahren 0
0
Gilles

Dies ist ein schwieriges Problem und in allgemeiner Form ein aktives Forschungsproblem. Ich glaube nicht, dass es jetzt ein Programm gibt, in das Sie nur ein paar Regexx einstecken müssen.

Ich würde Ihr Programm so formulieren, als würde ich versuchen, die Spuren eines vernetzten Programms zu vergleichen. Ich vermute, dass Leute, die Spuren von vernetzten oder gleichzeitigen Programmen vergleichen, dieses Problem angetreten haben und ihre eigenen Werkzeuge geschrieben haben, aber ich habe kein spezielles Beispiel.