Kennzeichnen Sie den ersten übereinstimmenden Eintrag an jedem Tag aus einer Liste von Datensätzen mit Standard * Nix-Werkzeugen

311
Stilez

Ich habe eine Textdatei, die Datensätze des Formulars enthält:

text text <2018.02.20-13.05.22> [dataset-london] text text text text text <2018.02.20-13.05.25> [dataset-newyork] text text text text text <2018.02.20-13.05.22> [dataset-moscow] text text text text text <2018.02.20-13.07.45> [dataset-london] text text text text text <2018.02.20-13.09.55> [dataset-paris] text text text 

Es gibt ungefähr 20 Datensätze, und Datensätze für jedes werden alle 15 Minuten um einen Datensatz hinzugefügt, wenn alles reibungslos läuft. Es kann jedoch Zeiten geben, in denen Datensätze nicht empfangen werden oder Datensätze schneller hinzugefügt werden.

Die Datensätze haben einen begrenzten Zeichensatz von [0-9a-zA-Z -._ @] sowie die Sonderzeichen <> [] als Trennzeichen, wie in den Beispielzeilen.

Um die Anzahl der Datensätze gering zu halten, werden Datensätze nach einiger Zeit als "sekundär" gekennzeichnet - nicht sehr wichtig / können ignoriert werden -, indem Sie am Ende der Zeile ein "*" hinzufügen. Der Algorithmus, den ich verwende, ist, die Datei durchzuleiten sedund regex find / replace zu verwenden, um Zeilen sedvorübergehend zu kennzeichnen, abhängig davon, ob es eine Basis gibt, um sie zu behalten, und dann erneut durchzuleiten, um die temporären Tags zu entfernen, und alle Zeilen ohne temporären Tag sind jetzt als sekundär markiert. Dies gibt einen Vorgeschmack darauf, wie ich das mache (ich habe die '\' - Fortsetzungen zur Klarheit weggelassen):

cat input_file | sed -E '/(`date '+%Y\.%m\.%d'`|`date -v-1d '+%Y\.%m\.%d'`)/ s/$/#/' | sed -E '/00\.00\.[0-9]>/ s/$/#/' | sed '/#$/! s/$/*/' | sed -E 's/#+$//'  > output_file 

Erklärung zum CLI-Code:

  1. Finden Sie jede Zeile mit einem Datum in den letzten 2 Tagen und fügen Sie eine temporäre Markierung ("+") hinzu.
  2. Findet jede Zeile mit Zeit innerhalb von 1 Minute nach Mitternacht (normalerweise der erste Datensatz des Tages für jeden Datensatz) und fügt eine temporäre Markierung hinzu.
  3. Alles, was nicht vorübergehend markiert ist, wird als sekundärer Datensatz betrachtet und mit einem *, ... versehen.
  4. Schließlich werden alle temporären Markierungen entfernt.

Es ist grob, funktioniert aber gut und ist flexibel.

Mein Problem ist, dass ich "den ersten Datensatz jedes Tages für jeden Datensatz" aufbewahren möchte. Im Moment verwende ich "innerhalb einer Minute nach Mitternacht" als Annäherungsmöglichkeit und verlasse mich in dieser Minute auf eindeutige Datensätze. Es funktioniert zu 100%, wenn alles reibungslos läuft, aber wenn es zu einem außergewöhnlichen Zeitraum kam, in dem das normale Record-Timing unterbrochen wurde, funktioniert es nicht. Wenn zum Beispiel alle Datensätze in einem bestimmten Zeitraum um 1 Minute verzögert wurden, sieht es so aus, als hätten wir in diesem Zeitraum keine "wichtigen Datensätze", da sie nicht herausfinden können, dass der Datensatz vom 2018.02.20-00.01.27 tatsächlich ist der erste Datensatz des Tages für diesen Datensatz, da ich "dumm" nach Datensätzen suche, die 20NN.NN.NN-00.00.NN>nur enthalten .

Ich kenne mich aus sed, mit awkdem ich weniger vertraut bin, vermute ich, dass es das Werkzeug ist, das ich brauche.

Wie gehe ich vor, um dies intelligenter zu gestalten, so kann es die tatsächliche erste Aufzeichnung jedes Tages oder die erste Aufzeichnung nach dem 15. eines Monats oder was auch immer bestimmen, um sicherzustellen, dass wichtige Datensätze nicht aufgrund ihres Seins nicht sichtbar bleiben als sekundär markiert.

0
Wenn ich es richtig verstanden habe, kann das meiner Meinung nach helfen. Ich habe Ihre "Erklärung des CLI-Codes" befolgt, um die Bedingungen festzulegen. `awk 'BEGIN ; ; gsub (/\./, "", line_date [1]); gsub (/\./, "", line_date [2]); if (mktime (line_date [1] "" line_date [2])> two_days_ago) ; sub (/ $ /, "*"); print} "Eingabedatei" Paulo vor 6 Jahren 0

0 Antworten auf die Frage