【问题标题】:sed remove section between curly bracessed 删除花括号之间的部分
【发布时间】:2019-06-14 06:14:50
【问题描述】:

由于缺少其他选项,我正在尝试从配置文件中删除部分 elasticsearch { * }。

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 和一些右大括号。

【问题讨论】:

  • 您在哪里找到了您使用的sed 命令?只有当收集的片段不包含elasticsearch 时,它才会简单地吞噬卷曲中的内容并打印。没有尝试保留结束卷曲;实际上,您可以争辩说它努力消除结束卷曲。它可能是为了回答有关从结构中最里面的一组花括号中提取信息的问题而发布的......?
  • 在这里:stackoverflow.com/questions/32588469/…。我尝试了一下,可惜我不是 sed wizz,只能写一些简单的命令...

标签: sed


【解决方案1】:

这可能对你有用(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

【讨论】:

  • 第一个解决方案对我有用,我只在弹性搜索字符串和左大括号之间添加了 [[:blank:]]* 以防有 > 1 个空格。谢谢
【解决方案2】:

这是 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}"
        }
  }
 }
}

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

【讨论】:

  • 这也适用于我以及这个 sed 解决方案。我选择了 sed,因为它在脚本中使用,但我通常对这段代码印象深刻 :)
【解决方案3】:

这就是你想要做的一切吗?

$ 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}"
        }
  }
 }
}

【讨论】:

  • 是的,这两个对我也有用,而且它们看起来比以前的答案要简单一些。我只想删除被花括号包围的 elasticsearch 部分,仅此而已。但是感谢您提供关于 awk 的另一种观点,我会对此进行研究。
猜你喜欢
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 2015-01-14
  • 2021-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多