2016-12-13 4 views
1

У меня есть файл, содержащий много блоков, как это:Как извлечь последний блок из файла

==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) 

Я хочу, чтобы извлечь последний блок, начиная с линией:

==XXXX== HEAP SUMMARY: 

Так в моем пример Я хочу извлечь только последний блок:

==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) 

Как я могу это сделать с помощью bash?

+1

[править] Ваш вклад, чтобы избавиться от всех '...' ы и сделать это бетон, проверяемым пример. Текст между вашими блоками так же важен, как и ваши блоки. Например, если на самом деле существует пустая строка между каждым блоком, в соответствии с вашим примером, то все, что вам нужно, это 'awk -v RS = '{s = $ 0} END {print s}' file', и если каждый блок имеет 8 строк, все, что вам нужно, это 'tail -8 file', но idk, если какой-либо из них действительно соответствует форматированию вашего ввода. –

ответ

1

Использование grep -zoP и отрицательное опережения регулярного выражения:

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 обрабатывает файл данных как нуль вместо новой строки завершается
  • (?![\s\S]*==\w{4}== HEAP SUMMARY:) отрицательный предпросмотр, утверждающими мы не имеем еще один экземпляр то же самое в файле ниже.

RegEx Demo

1

, если у вас есть tac, это может быть простой

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

Если вы знаете, что блоки всегда длинные 9 строк, вы можете просто использовать tail:

tail -n9 file 
1

С sed:

$ 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) 

Вот как это работает:

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 

Каждый раз, когда это встречает HEAP SUMMARY, он читает все строки до следующего ERROR SUMMARY в области шаблона. Затем он проверяет, была ли достигнута последняя строка; если да, пространство шаблонов печатается, а если нет, оно удаляется.

0

Если последняя строка файла имеет номер блока, это будет получить номер блока быстро (не чтение всего файла, чтобы узнать, какой номер то есть):

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

Тогда мы можем выбрать все строки, которые имеют такой номер блока от конца до:

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

Это может работать для вас (GNU СЭД):

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

При столкновении HEAP SUMMARY: замените то, что находится в удерживаемом пространстве (HS) текущей линией. Для любого другого шаблона присоедините эту строку к HS. Удалите все строки, кроме последнего, когда пространство шаблона (PS) обменивается с HS и PS распечатывается.

0

Использование номера перед данными как идентификационный номер/группа:

id=$(tail -n1 file | grep -Po '(?<=\=\=)[0-9]*') && grep "$id" file |tail -n+2 
Смежные вопросы