2016-12-13 3 views
1

zu extrahieren habe ich eine Datei viele Blöcke wie folgt enthält:Wie ein letzten Block aus einer Datei

==9673== 
==9673== HEAP SUMMARY: 
==9673==  in use at exit: 0 bytes in 0 blocks 
==9673== total heap usage: 75,308 allocs, 75,308 frees, 7,099,382 bytes allocated 
==9673== 
==9673== All heap blocks were freed -- no leaks are possible 
==9673== 
==9673== For counts of detected and suppressed errors, rerun with: -v 
==9673== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 
.... 
.... 
.... 
.... 

==9655== 
==9655== HEAP SUMMARY: 
==9655==  in use at exit: 0 bytes in 0 blocks 
==9655== total heap usage: 75,308 allocs, 75,308 frees, 7,099,382 bytes allocated 
==9655== 
==9655== All heap blocks were freed -- no leaks are possible 
==9655== 
==9655== For counts of detected and suppressed errors, rerun with: -v 
==9655== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 

.... 
.... 
.... 

==9699== 
==9699== HEAP SUMMARY: 
==9699==  in use at exit: 0 bytes in 0 blocks 
==9699== total heap usage: 75,308 allocs, 75,308 frees, 7,099,382 bytes allocated 
==9699== 
==9699== All heap blocks were freed -- no leaks are possible 
==9699== 
==9699== For counts of detected and suppressed errors, rerun with: -v 
==9699== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 

Ich mag mit der Linie Beginn den letzten Block extrahieren:

==XXXX== HEAP SUMMARY: 

in meinem So Beispiel Ich möchte nur den letzten Block extrahieren:

==9699== HEAP SUMMARY: 
==9699==  in use at exit: 0 bytes in 0 blocks 
==9699== total heap usage: 75,308 allocs, 75,308 frees, 7,099,382 bytes allocated 
==9699== 
==9699== All heap blocks were freed -- no leaks are possible 
==9699== 
==9699== For counts of detected and suppressed errors, rerun with: -v 
==9699== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 

Wie kann ich das mit bash?

+1

[Bearbeiten] Ihre Eingabe aller '...' s, um loszuwerden, und es ist ein Beton, prüfbare Beispiel machen. Der Text zwischen deinen Blöcken ist genauso wichtig wie deine Blöcke. Zum Beispiel, wenn es wirklich eine Leerzeile zwischen jedem Block gibt, wie Ihr Beispiel momentan impliziert, dann brauchen Sie nur 'awk -v RS =' {s = $ 0} END {Druck s} 'Datei' und wenn jeder Block 8 Zeilen hat Alles, was Sie brauchen, ist 'tail -8 file', aber idk, wenn einer der beiden so aussieht wie Ihre Eingabe formatiert ist oder nicht. –

Antwort

1

Mit grep -zoP und einem negativen Look-Ahead-regex:

grep -zoP '==\w{4}== HEAP SUMMARY:(?![\s\S]*==\w{4}== HEAP SUMMARY:)[\s\S]*\z' file 

==9699== HEAP SUMMARY: 
==9699==  in use at exit: 0 bytes in 0 blocks 
==9699== total heap usage: 75,308 allocs, 75,308 frees, 7,099,382 bytes allocated 
==9699== 
==9699== All heap blocks were freed -- no leaks are possible 
==9699== 
==9699== For counts of detected and suppressed errors, rerun with: -v 
==9699== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 
  • -z behandelt die Daten als null-Datei anstelle von neuer Zeile beendet beendet
  • (?![\s\S]*==\w{4}== HEAP SUMMARY:) negativ Look-Ahead, die wir nicht haben, eine andere Instanz behauptet von das Gleiche in der Datei unten.

RegEx Demo

1

wenn Sie tac haben, könnte dies die einfachste

$ tac file | awk '1; /==....== HEAP SUMMARY/{exit}' | tac 
1

Wenn Sie wissen, dass die Blöcke immer neun Zeilen lang sind, können Sie einfach tail verwenden können:

tail -n9 file 
1

Mit sed:

Hier
$ sed -n '/HEAP SUMMARY/{:a;/ERROR SUMMARY/bb;N;ba;:b;$p;d}' infile 
==9699== HEAP SUMMARY: 
==9699==  in use at exit: 0 bytes in 0 blocks 
==9699== total heap usage: 75,308 allocs, 75,308 frees, 7,099,382 bytes allocated 
==9699== 
==9699== All heap blocks were freed -- no leaks are possible 
==9699== 
==9699== For counts of detected and suppressed errors, rerun with: -v 
==9699== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 

ist, wie das funktioniert:

sed -n '     # Do not print lines at end of each cycle 
    /HEAP SUMMARY/ {  # If line matches "HEAP SUMMARY" 
     :a     # Label to jump back to 
     /ERROR SUMMARY/bb # If line matches "ERROR SUMMARY", jump to :b 
     N     # Append next line to pattern space 
     ba     # Jump to :a 
     :b     # Label to jump forward to 
     $p     # If we are on the last line, print pattern space 
     d     # Delete pattern space 
    } 
' infile 

Jedesmal, wenn diese HEAP SUMMARY trifft, es liest alle Zeilen bis zur nächsten ERROR SUMMARY in den Musterraum. Dann überprüft es, ob die letzte Zeile erreicht wurde. Wenn ja, wird der Musterbereich gedruckt, andernfalls wird er gelöscht.

0

Wenn die letzte Zeile der Datei auch die Blocknummer hat, wird dies die Blocknummer schnell bekommen (kein Lesen der gesamten Datei zu finden, welche Nummer das ist):

n="$(tail -n1 infile | awk '{print $1}')" 

Dann können wir wählen alle Linien, die solche Blocknummer von dem Ende nach oben haben:

tac infile | awk -vn="$n" '!($1~n){exit};1'| tac 
0

Dies könnte für Sie arbeiten (GNU sed):

sed '/HEAP SUMMARY:/h;//!H;$!d;x' file 

Wenn Sie auf HEAP SUMMARY: stoßen, ersetzen Sie, was sich im Laderaum (HS) befindet, durch die aktuelle Zeile. Für jedes andere Muster die Linie an den HS anhängen. Löschen Sie alle Zeilen außer der letzten, wenn der Musterbereich (PS) mit dem HS vertauscht ist und der PS ausgedruckt wird.

0

Mit Nummer vor Daten als id/Gruppennummer:

id=$(tail -n1 file | grep -Po '(?<=\=\=)[0-9]*') && grep "$id" file |tail -n+2 
Verwandte Themen