sed удалить раздел между фигурными скобками - PullRequest
0 голосов
/ 13 июня 2019

Я пытаюсь удалить разделasticsearch {*} из файла конфигурации из-за отсутствия других опций.

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

Я попытался отменить команду sed, найденную в stackoverflow, но удаляет окончание} изфайлы конфигурации тоже.

[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 голосов
/ 13 июня 2019

Вот один в 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}"
        }
  }
 }
}

Проверено только с предоставленными данными.

0 голосов
/ 14 июня 2019

Это все, что вы пытаетесь сделать?

$ 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}"
        }
  }
 }
}
0 голосов
/ 13 июня 2019

Это может сработать для вас (GNU sed):

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

Соберите строки, начинающиеся elasticsearch { и заканчивающиеся }, и удалите их.

N.B. При этом используется флаг M для многострочного совпадения для конечного условия, специфичного для GNU. Альтернатива:

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