使用sed或awk从文件中删除功能

时间:2015-11-04 07:37:20

标签: linux bash awk command-line sed

我想删除功能'引擎'地图“{...”foobar“...}'。

我尝试了很多方面,它很难,因为它有空行和最后的'}',分隔符不起作用

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'/ engine /,/ ^ \ s \ s} $ / d'文件

但删除了所有引擎功能,我只需要一个包含“foobar”的功能,也许一个模式匹配所有内容甚至换行,直到foobar这样的东西:

  

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

我有可能吗?

2 个答案:

答案 0 :(得分:1)

当你匹配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返回匹配数:split(string, array [, fieldsep [, seps ] ])

  

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

答案 1 :(得分: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