Grep für Block um eine Fehlermeldung

0

Ich möchte nach dem Block von Protokollen um eine bestimmte Fehlermeldung suchen. Angenommen, ich weiß, mein Protokoll sieht folgendermaßen aus:

[----] I, [2014-04-10T19:12:36.294512 #1910:e93004]  INFO -- : Started GET "/ems_infra/new"  for 4.2.2.2 at 2014-04-10 15:12:36 -0400 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] F, [2014-04-10T19:12:36.346380 #1910:e93004] FATAL -- : Error caught: [NoMethodError] undefined method `invert' for nil:NilClass
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.369320 #1910:e93004]  INFO -- : Completed 200 OK in 69ms (Views: 22.5ms | ActiveRecord: 0.0ms)

Ich interessiere mich für diesen ganzen Block. Gibt es eine Möglichkeit, mein Grep um den FATALFehler herum zu zentrieren und nach oben Started GETund unten zu greifen Completed 200 OK?

Ich weiß, dass grep -B 123 -A 456 "FATAL" file.txtdas den Trick macht, aber dazu muss ich im Voraus wissen, wie weit ich FATALvon der ersten Zeile (123) und der letzten Zeile (456) entfernt bin [1].

[1] http://unixhelp.ed.ac.uk/CGI/man-cgi?grep

CHK
quelle

Antworten:

0

Ich fürchte, grep hat keine solche Möglichkeit. Perl und / oder Python könnte. Aus dem Kopf (ohne viel darüber nachzudenken) habe ich mir die folgende Awk-Combo ausgedacht.

 awk '/Started GET/{print ""};1' blurble | awk 'BEGIN{RS=ORS="\n\n";FS=OFS="\n"}/FATAL/{print $0}'

Ausgehend von einem Protokollblock, der aus Ihrem Snippet (x4) erstellt wurde, und ein paar zusätzlichen "other log" -Zeilen, die eingeworfen und zwei "FATAL" -Zeilen entfernt wurden, werden zwei Segmente gedruckt:

[----] I, [2014-04-10T19:12:36.294512 #1910:e93004]  INFO -- : Started GET "/ems_infra/new"  for 4.2.2.2 at 2014-04-10 15:12:36 -0400 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.369320 #1910:e93004]  INFO -- : Completed 200 OK in 69ms (Views: 22.5ms | ActiveRecord: 0.0ms)
[----] I, [2014-04-10T19:12:36.294512 #1910:e93004]  INFO -- : Started GET "/ems_infra/new"  for 4.2.2.2 at 2014-04-10 15:12:36 -0400 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] F, [2014-04-10T19:12:36.346380 #1910:e93004] FATAL -- : Error caught: [NoMethodError] undefined method `invert' for nil:NilClass
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.369320 #1910:e93004]  INFO -- : Completed 200 OK in 69ms (Views: 22.5ms | ActiveRecord: 0.0ms)
[----] I, [2014-04-10T19:12:36.294512 #1910:e93004]  INFO -- : Started GET "/ems_infra/new"  for 4.2.2.2 at 2014-04-10 15:12:36 -0400 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.369320 #1910:e93004]  INFO -- : Completed 200 OK in 69ms (Views: 22.5ms | ActiveRecord: 0.0ms)
[----] I, [2014-04-10T19:12:36.294512 #1910:e93004]  INFO -- : Started GET "/ems_infra/new"  for 4.2.2.2 at 2014-04-10 15:12:36 -0400 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] F, [2014-04-10T19:12:36.346380 #1910:e93004] FATAL -- : Error caught: [NoMethodError] undefined method `invert' for nil:NilClass
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.369320 #1910:e93004]  INFO -- : Completed 200 OK in 69ms (Views: 22.5ms | ActiveRecord: 0.0ms)

Das Ausführen der beiden awks gegen die Datei (ich nannte sie blurble) ergibt diese Ausgabe:

[----] I, [2014-04-10T19:12:36.294512 #1910:e93004]  INFO -- : Started GET "/ems_infra/new"  for 4.2.2.2 at 2014-04-10 15:12:36 -0400 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] F, [2014-04-10T19:12:36.346380 #1910:e93004] FATAL -- : Error caught: [NoMethodError] undefined method `invert' for nil:NilClass
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.369320 #1910:e93004]  INFO -- : Completed 200 OK in 69ms (Views: 22.5ms | ActiveRecord: 0.0ms)

[----] I, [2014-04-10T19:12:36.294512 #1910:e93004]  INFO -- : Started GET "/ems_infra/new"  for 4.2.2.2 at 2014-04-10 15:12:36 -0400 
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs 
[----] F, [2014-04-10T19:12:36.346380 #1910:e93004] FATAL -- : Error caught: [NoMethodError] undefined method `invert' for nil:NilClass
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.345863 #1910:e93004]  INFO -- : other random logs
[----] I, [2014-04-10T19:12:36.369320 #1910:e93004]  INFO -- : Completed 200 OK in 69ms (Views: 22.5ms | ActiveRecord: 0.0ms)
basteln
quelle
0

Ich habe ein Skript, das helfen könnte: https://github.com/jakl/blocks

./blocks.pl --delim 'Started GET | Completed 200 OK' --term 'FATAL'

Es teilt Ihr Protokoll in Blöcke auf, die mit --delim beginnen oder enden, und druckt diejenigen, die --term enthalten

Jakl
quelle
0

Hier ist ein Einzeiler mit sed

sed -n '/Started/,/Completed/H;/Completed/{z;x;/FATAL/p}' log

Ein Liner wurde zur Erklärung erweitert

# do not print lines unless explicitly told to do so
sed -n '

  # put everything between Started and Completed in hold space
  /Started/,/Completed/ H;

  # if at Completed
  /Completed/ {

    # empty the pattern space
    z;

    # switch hold space with pattern space
    x;

    # if FATAL in pattern space then print
    /FATAL/p

  }

' log

Beachten Sie, dass dies eine leere Zeile zwischen jedem Block ausgibt. Die leere Zeile stammt aus der z;x;Combo. zleert den Musterraum. xSchalter halten Raum mit Musterraum. das heißt, nachdem z;x;es eine leere Zeile im Laderaum gibt. Wenn Sie den Pattern-Bereich nicht leeren, bevor Sie mit Hold-Bereich wechseln, wird die letzte Zeile des vorherigen Blocks im nächsten Block angezeigt. Ich habe versucht, dies zu umgehen, um die Leerzeile zu verhindern, aber das machte den Code viel verworrener.

Wenn Sie die leere Zeile stört, können Sie sie mit einem anderen sed-Befehl herausfiltern.

sed -n '/Started/,/Completed/H;/Completed/{z;x;/FATAL/p}' log | sed '/^$/d'

oder Sie können einen Marker setzen, der die Ausgabe dieses Befehls fast wie grep macht

sed -n '/Started/,/Completed/H;/Completed/{z;x;/FATAL/p}' log | sed 's/^$/--/'

Hier ist die einfachste Lösung, die ich mir ausgedacht habe und die Leerzeile beseitigt

sed -n '

  # replace hold space with pattern space
  /Started/ h

  /Started/,/Completed/ {

    # skip the first line because it is already in hold space
    /Started/ n

    # append pattern space to hold space
    H
  }

  /Completed/ {

    # switch hold space with pattern space
    x

    # if FATAL in pattern space then print
    /FATAL/ p
  }

' log

das gleiche wie der obligatorische Einzeiler

sed -n '/Started/h;/Started/,/Completed/{/Started/n;H};/Completed/{x;/FATAL/p}' log
lesmana
quelle