2015-11-04 67 views
1

我想删除函数“engine”map“{...”foobar“...}”。使用sed或awk从文件中删除功能

我在很多方面尝试,它很难,因为它在结束的空行和“}”分隔符不起作用

mainfunc { 

    var = "baz" 

    engine "map" { 

    func { 

     var0 = "foo" 
     border = { 1, 1, 1, 1 } 
     var1 = "bar" 
    } 
    } 
} 

mainfunc { 

    var = "baz" 

    engine "map" { 

    func { 

     var0 = "foo" 
     border = { 1, 1, 1, 1 } 
     var1 = "foobar" 
    } 
    } 
} 

... # more functions like 'mainfunc' 

我试图

sed的“/发动机/,/^\ S \ S} $/d”文件

但删除了每个引擎功能,我只需要包含‘foobar的’,也许是模式匹配的一切,甚至换行,直到foobar的是这样的一种:

sed的 '/engine(.*)foobar/,/^\s\s}$/d' 文件

I'ts可能吗?

回答

1

尝试:

sed '/engine/{:a;N;/foobar/{N;N;d};/ }/b;ba}' filename 

或:

awk '/engine/{c=1}c{b=b?b"\n"$0:$0;if(/{/)a++;if(/}/)a--;if(!a){if(b!~/foobar/)print b;c=0;b="";next}}!c' filename 
+0

人,你摇滚! 谢谢! – Ferragam

0

我会简单的计数打开/关闭括号的数量,当你匹配engine "map",不能如果GAWK这只能

awk ' 
    /^[ \t]*engine "map"/ { 
    ship=1; # ship is used as a boolean 
    b=0 # The factor between open/close brackets 
    } 
    ship { 
    b += split($0, tmp, "{"); # Count numbers of { in line 
    b -= split($0, tmp, "}"); # Count numbers of } in line 
    # If open/close brackets are equal the function ends 
    if(b==0) { 
     ship = 0; 
    } 
    # Ship the rest (printing) 
    next; 
    } 
    1 # Print line 
' file 

斯普利特返回匹配的数目说:split(string, array [, fieldsep [, seps ] ])

将 字符串分为由fieldpat 定义的部分,并将数组中的部分和 seps数组中的分隔符字符串进行存储。第一部分储存在 array[1],第二部分在array[2]之后,等等 。第三个参数fieldpat是 一个描述字符串中字段的正则表达式(就像FPAT是描述输入记录中字段的正则表达式 一样)。 它可能是一个正则表达式常量或一个字符串。 如果省略fieldpat,则使用FPAT的值。 patsplit()返回创建的元素的数量。