2016-04-28 5 views
2

У меня есть очень большой текстовый файл (40 ГБ gzipped), где блоки данных разделены //.Выберите полный блок текста, ограниченный некоторыми символами

Как выбрать блоки данных, где определенная строка соответствует некоторому критерию? То есть, может ли шаблон grep и расширить выделение в обоих направлениях на разделитель //? Я не могу делать никаких предположений относительно размера блока и положения линии.

not interesting 1 
not interesting 2 
// 
get the whole block 1 
MATCH THIS LINE 
get the whole block 2 
get the whole block 3 
// 
not interesting 1 
not interesting 2 
// 

Я хочу, чтобы выбрать блок данных с MATCH THIS LINE:

get the whole block 1 
MATCH THIS LINE 
get the whole block 2 
get the whole block 3 

Я попытался sed, но не могу получить мою голову вокруг определения шаблона. Это, например, должно совпадать с // к MATCH THIS LINE:

sed -n -e '/\/\//,/MATCH THIS LINE/ p' file.txt 

Но это терпит неудачу сопоставления //.

Возможно ли достичь этого с помощью инструментов командной строки GNU?

ответ

5

С GNU awk (из-за нескольких символьные RS), вы можете установить разделитель для //, так что каждая запись является // -delimited набор символов:

 
$ awk -v RS="//" '/MATCH THIS LINE/' file 

get the whole block 1 
MATCH THIS LINE 
get the whole block 2 
get the whole block 3 

ПримечаниеЭтот оставляет пустую строку выше и ниже, потому что он ловит новую строку сразу после // и отпечатывает ее обратно, а также последнюю до // в конце. Чтобы удалить их, вы можете проехать до awk 'NF'.

Для печати разделитель между блоками данных, вы можете сказать (спасибо 123):

awk -v RS="//" '/MATCH THIS LINE/{print RT $0 RT}' file 
+0

Perfect, который работает. Можно ли сохранить '//' и распечатать его обратно на выходе? –

+0

@MartinPreusse, как именно? Выше и ниже блока? – fedorqui

+0

Ниже. То есть сохраняйте разделитель между блоками данных. –

Смежные вопросы