Frage

Ich versuche, ein Protokoll -Parsing -Skript zu schreiben, um fehlgeschlagene Ereignisse zu extrahieren. Ich kann diese mit Grep ziehen:

$ grep -A5 "FAILED" log.txt

2008-08-19 17:50:07 [7052] [14] DEBUG:      data: 3a 46 41 49 4c 45 44 20 20 65 72 72 3a 30 32 33   :FAILED  err:023
2008-08-19 17:50:07 [7052] [14] DEBUG:      data: 20 74 65 78 74 3a 20 00                            text: .
2008-08-19 17:50:07 [7052] [14] DEBUG:    Octet string dump ends.
2008-08-19 17:50:07 [7052] [14] DEBUG: SMPP PDU dump ends.
2008-08-19 17:50:07 [7052] [14] DEBUG: SMPP[test] handle_pdu, got DLR
2008-08-19 17:50:07 [7052] [14] DEBUG: DLR[internal]: Looking for DLR smsc=test, ts=1158667543, dst=447872123456, type=2
--
2008-08-19 17:50:07 [7052] [8] DEBUG:      data: 3a 46 41 49 4c 45 44 20 20 65 72 72 3a 30 32 34   :FAILED  err:024
2008-08-19 17:50:07 [7052] [8] DEBUG:      data: 20 74 65 78 74 3a 20 00                            text: .
2008-08-19 17:50:07 [7052] [8] DEBUG:    Octet string dump ends.
2008-08-19 17:50:07 [7052] [8] DEBUG: SMPP PDU dump ends.
2008-08-19 17:50:07 [7052] [8] DEBUG: SMPP[test] handle_pdu, got DLR
2008-08-19 17:50:07 [7052] [8] DEBUG: DLR[internal]: Looking for DLR smsc=test, ts=1040097716, dst=447872987654, type=2

Was mich interessiert, ist für jeden Block der Fehlercode (dh der "023" -Teil von ": fehlgeschlagener Err: 023" in der ersten Zeile) und die DST -Nummer (dh "447872123456" von "DST = 447872123456" in der letzten Zeile.)

Kann jemand bei einem Shell-Ein-Liner helfen, diese beiden Werte zu extrahieren oder einige Hinweise darauf zu geben, wie ich mich daran nähern sollte?

War es hilfreich?

Lösung

grep -A 5 FAILED log.txt | \              # Get FAILED and dst and other lines
    egrep '(FAILED|dst=)' | \             # Just the FAILED/dst lines
    egrep -o "err:[0-9]*|dst=[0-9]*" | \  # Just the err: and dst= phrases
    cut -d':' -f 2 | \                    # Strip "err:" from err: lines
    cut -d '=' -f 2 | \                   # Strip "dst=" from dst= lines
    xargs -n 2                            # Combine pairs of numbers

023 447872123456
024 447872987654

Wie bei allen "One" -Linern gibt es mit ziemlicher Sicherheit eine elegantere Möglichkeit, dies zu tun. Ich finde jedoch den iterativen Ansatz sehr erfolgreich, um das zu bekommen, was ich will: Beginnen Sie mit zu vielen Informationen (Ihr Grep) und beschränken schneiden).

Während die Verwendung der Linux -Toolbox mehr Zeilen einnimmt, müssen Sie nur die Grundlagen einiger Befehle kennen, um so gut wie alles zu tun, was Sie wollen. Eine Alternative besteht darin, awk, python oder andere Skriptsprachen zu verwenden, für die spezialisiertere Programmierkenntnisse erforderlich sind, aber weniger Bildschirmraum einnehmen.

Andere Tipps

Eine einfache Lösung in Ruby, hier ist filter.rb:

#! /usr/bin/env ruby
File.read(ARGV.first).scan(/:FAILED\s+err:(\d+).*?, dst=(\d+),/m).each do |err, dst|
  puts "#{err} #{dst}"
end

Führen Sie es mit:

ruby filter.rb my_log_file.txt

Und du bekommst:

023 447872123456
024 447872987654

Wenn es immer die gleiche Anzahl von Feldern gibt, könnten Sie gerade gerecht

grep -A5 "FAILED" log.txt | awk '$24~/err/ {print $24} $12~/dst/{print $12}' error.txt

err:023
dst=447872123456,
err:024
dst=447872987654,

Und abhängig davon, wie der Rest der Datei aussieht, können Sie möglicherweise den Grep alle zusammenspringen.

Das "$ 24 ~/ err/ {print $ 24}"Teil sagt awk, die Feldnummer 24 zu drucken, wenn es ERR, ~/ xxx/ wobei XXX ein regulärer Ausdruck ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top