2012-03-26 4 views
0

У меня есть журнал следующего форматаSED соответствие несколько шаблона линии

<< 
[ABC] some other data 
some other data 
>> 

<< 
DEF some other data 
some other data 
>> 

<< 
[ABC] some other data 
some other data 
>> 

Я хотел, чтобы выбрать все журналы, которые оказывают ABC ожидаемых результат

<< 
[ABC] some other data 
some other data 
>> 

<< 
[ABC] some other data 
some other data 
>> 

Что будет выражение для SED команды? Для извлечения содержимого ч/б < < >> выражение будет

sed -e '/<</,/>>/!d' 

Но как я могу заставить его иметь [ABC] в ч/б

ответ

1

Это работает на моей стороне:

awk '$0~/ABC/{print "<<";print;getline;print;getline;print }' temp.txt 

испытанной, как показано ниже:

pearl.242> cat temp.txt 
<< 
[ABC] some other data 
some other data 
>> 
<< 
DEF some other data 
some other data 
>> 

nkeem 

<< 
[ABC] some other data 
some other data 
>> 
pearl.243> awk '$0~/ABC/{print "<<";print;getline;print;getline;print }' temp.txt 
<< 
[ABC] some other data 
some other data 
>> 
<< 
[ABC] some other data 
some other data 
>> 
pearl.244> 

Если вы выигрыш хотите жестко закодировать это заявление print "<<";, тогда вы можете пойти на следующее:

pearl.249> awk '$0~/ABC/{print x;print;getline;print;getline;print}{x=$0}' temp.txt 
<< 
[ABC] some other data 
some other data 
>> 
<< 
[ABC] some other data 
some other data 
>> 
pearl.250> 
0

Ко мне, СЭД является линия на основе. Вы, вероятно, можете говорить о том, что это многострочная линия, но легче было бы начать работу с awk или perl, а не пытаться сделать это в sed.

Я хотел бы использовать Perl и сделать небольшую государственную машину, как этот псевдо-код (я не гарантирую, что это будет ловить каждую мелочь, что вы пытаетесь достичь)

state = 0; 
for each line 
    if state == 0 
     if line == '<<' 
      state = 1; 
    if state == 1 
     If line starts with [ABC] 
      buffer += line 
      state =2 
    if state == 2 
     if line == >> 
      do something with buffer 
      state = 0 
     else 
      buffer += line; 

http://www.catonmat.net/blog/awk-one-liners-explained-part-three/ Смотрите также для получения подсказок о том, как вы могли бы сделать это с AWK как 1 лайнер ...

2

Это может работать для вас:

sed '/^<</,/^>>/{/^<</{h;d};H;/^>>/{x;/^<<\n\[ABC\]/p}};d' file 
<< 
[ABC] some other data 
some other data 
>> 
<< 
[ABC] some other data 
some other data 
>> 

СЭД оснащен регистр называется hold space (HS).

Вы можете использовать HS для сбора данных, представляющих интерес. В этом случае линии между /^<</,/^>>/

h заменяет все, что в ГС с тем, что в шаблоне пространства (PS)

H добавляет символ новой строки \n, а затем PS к HS

x свопов HS для PS

NB Это удаляет все строки, отличные от <<...>>, содержащие [ABC]. Если вы хотите сохранить другие линии использовать:

sed '/^<</,/^>>/{/^<</{h;d};H;/^>>/{x;/^<<\n\[ABC\]/p};d}' file 
<< 
[ABC] some other data 
some other data 
>> 


<< 
[ABC] some other data 
some other data 
>> 
+0

второе выражение приносит все. –

+0

Нет, он печатает эти строки в пределах, которые соответствуют '/^<< \ n \ [ABC \]/p' и любые линии вне диапазона в целом. В этом случае пустые строки между '/^<> /' – potong

+0

N.B. '/^<< \ n \ [ABC \]/p' может быть сокращено до'/ABC/p' – potong

0

TXR: встроенный для многострочного вещания.

@(collect) 
<< 
[ABC] @line1 
@line2 
>> 
@ (output) 
>> 
[ABC] @line1 
@line2 
<< 

@ (end) 
@(end) 

Пробег:

$ txr data.txr data 
>> 
[ABC] some other data 
some other data 
<< 

>> 
[ABC] some other data 
some other data 
<< 

Очень основной материал; вы, вероятно, лучше избегаете придерживаться awk до тех пор, пока у вас не будет очень сложного многоканального извлечения с нерегулярными данными с многочисленными случаями, большим количеством гнездования и т. д.

Если журнал очень большой, мы должны написать @(collect :vars()), чтобы сбор не подразумевает накопления списков; то работа будет работать в постоянной памяти.

Кроме того, если журналы не всегда являются двумя строками, это становится немного сложнее. Мы можем использовать вложенный сбор, чтобы собрать переменное количество строк.

@(collect :vars()) 
<< 
[ABC] @line1 
@ (collect) 
@line 
@ (until) 
>> 
@ (end) 
@ (output) 
>> 
[ABC] @line1 
@ {line "\n"} 
<< 

@ (end) 
@(end) 
Смежные вопросы