sed删除花括号之间的部分

时间:2019-06-13 06:03:16

标签: sed

由于缺少其他选项,我试图从配置文件中删除弹性搜索{*}部分。

output {
  if [env] {
      if [containerimage] and [containerimage] != "apache" {
        file {
          path => "/var/log/logstash/logs/%{[env]}/%{file}-%{+YYYY-MM-dd}"
        }
        elasticsearch {
          hosts => ["{{elasticsearch/host}}:{{elasticsearch/port}}"]
          template_overwrite => true
       } 
  }
 }
}

我试图撤消在stackoverflow上找到的sed命令,但它也从配置文件中删除了结尾}。

[root@indexer conf.d]# sed '/{/{:1; /}/!{N; b1}; /elasticsearch/!p}; d' example              
output {
  if [env] {
      if [containerimage] and [containerimage] != "apache" {
        file {
          path => "/var/log/logstash/logs/%{[env]}/%{file}-%{+YYYY-MM-dd}"

可能是由于}}必须存在于cfg中。有什么办法可以解决这个问题?预先感谢

编辑:

其他一些实验:

sed '/elasticsearch {/{:1; /}/!{N; b1} }; /elasticsearch/!p; d' example 
output {
  if [env] {
      if [containerimage] and [containerimage] != "apache" {
        file {
          path => "/var/log/logstash/logs/%{[env]}/%{file}-%{+YYYY-MM-dd}"
        }
                  template_overwrite => true
            } 
           }
  }
}

但是保留template_overwrite和一些右括号。

3 个答案:

答案 0 :(得分:0)

这可能对您有用(GNU sed):

sed '/^\s*elasticsearch {$/{:a;N;/^\s*}$/M!ba;d}' file

收集从elasticsearch {开始到}结束的行并将其删除。

这将M标志用于特定于GNU sed的结束条件的多行匹配。另一种选择:

sed -n '/^\s*elasticsearch {$/{:a;n;/^\s*}$/!ba;d};p' file

答案 1 :(得分:0)

这是awk中的一个:

awk '
BEGIN {
    RS="^$"                            # read in the whole file
    c=1                                # brace counter
}
{
    match($0,/\n? *elasticsearch \{/)  # find the start of string to remove
    print substr($0,1,RSTART-1)        # RUNNING OUT OF BATTERY
    $0=substr($0,RSTART+RLENGTH)
    while(c>0) {
        match($0,/(\{|\} *\n*)/)
        if(substr($0,RSTART,1)=="{")
            c++
        else
            c--
        $0=substr($0,RSTART+RLENGTH)
    }
    print
}' file

输出:

output {
  if [env] {
      if [containerimage] and [containerimage] != "apache" {
        file {
          path => "/var/log/logstash/logs/%{[env]}/%{file}-%{+YYYY-MM-dd}"
        }
  }
 }
}

仅使用提供的数据进行了测试。

答案 2 :(得分:0)

这就是您要尝试的全部吗?

$ sed '/elasticsearch[[:space:]]*{/,/^[[:space:]]*}/d' file
output {
  if [env] {
      if [containerimage] and [containerimage] != "apache" {
        file {
          path => "/var/log/logstash/logs/%{[env]}/%{file}-%{+YYYY-MM-dd}"
        }
  }
 }
}

以上内容适用于任何POSIX sed。如果这还不是您所需要的,请编辑您的问题以显示更真实的示例,以便我们为您提供帮助。 FWIW我真的不会做上面的事,因为如果/当您的需求略有不同时,它是不可扩展的,我会这样做:

$ awk '/elasticsearch[[:space:]]*{/{f=1} !f; /^[[:space:]]*}/{f=0}' file
output {
  if [env] {
      if [containerimage] and [containerimage] != "apache" {
        file {
          path => "/var/log/logstash/logs/%{[env]}/%{file}-%{+YYYY-MM-dd}"
        }
  }
 }
}