2012-03-26 34 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命令的表达? 对于获取内容的B/W < < >>表达将

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

但我怎么能强迫它有[ABC]中的B/W

回答

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> 

如果DONOT想硬编码此声明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 
>> 

的sed配备了一个寄存器称为hold space(HS)。

您可以使用HS来收集感兴趣的数据。在/^<</,/^>>/

h替换掉在HS与什么是在图案空间(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

第二个表达式带来了一切。 – 2012-03-26 10:49:02

+0

不,它会在符合'/^<< \ n \ [ABC \]/p'的范围内打印那些行,以及完全在范围外的任何行。在这种情况下,“/^<> /' – potong 2012-03-26 11:38:18

+0

N.B. '/^<< \ n \ [ABC \]/p'可以缩写为'/ ABC/p' – potong 2012-03-26 11:45:01

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)