substituir uma linha de 6 linhas após a correspondência da string

2

Eu quero alterar o notification_interval de 15 para 2 somente para o bloco File_Check.

Eu tentei alterar a linha 6 depois de corresponder à linha File_Check com:

sed -e '6 /File_Check/ s/15/2/g' file.txt 

mas não funcionou.

Aqui está file.txt:

define service {
    host_name                       local
    service_description             Memory
    check_command                   check_nrpe
    max_check_attempts              3
    check_interval                  5
    retry_interval                  1
    check_period                    24x7
    notification_interval           15
    contact_groups                  test
    notification_period             24x7
    notifications_enabled           0
    notification_options            w,c
    _xiwizard                       nrpe
    register                        1
    }

define service {
    host_name                       local
    service_description             File_Check
    check_command                   check_nrpe
    max_check_attempts              3
    check_interval                  5
    retry_interval                  1
    check_period                    24x7
    notification_interval           15
    contact_groups                  test
    notification_period             24x7
    notifications_enabled           0
    notification_options            w,c
    _xiwizard                       nrpe
    register                        1
    }
    
por Quay 01.03.2016 / 21:00

3 respostas

3
sed '/File_Check/,/contact_groups/ s/\(notification_interval\s*\)15//g' file.txt

Isto começará em uma linha que corresponde a "File_Check" e terminará em uma linha correspondente a "contact_groups" e substituirá "15" por "2" quando "notification_interval" estiver nessa linha antes do "15".

    
por 01.03.2016 / 21:42
3

Usar perl é outra alternativa:

perl -p00 -e 'if (/File_Check/) {s/(notification_interval\s*)15/${1}2/}' file.txt

A opção -00 diz ao perl para ler sua entrada no "modo de parágrafo", blocos de texto separados por linhas em branco. A operação s/// é aplicada apenas ao parágrafo que contém File_Check .

    
por 01.03.2016 / 22:03
1

Lógica alternativa em sed :

sed -e '/File_Check/{
          :loop
          /notification_interval/!{
            N;
            b loop
          }; s/\(notification_interval\s*\)[0-9]\+//
        }' your_file

Explicação

Quando você corresponder a File_Check , continue lendo novas linhas e adicionando-as ao espaço padrão até que você corresponda a notification_interval . Quando você combina, faça a substituição de regex que você precisa. A substituição que eu escolho aqui é substituir notification_interval\s*[0-9]\+ ( notification_interval seguido por qualquer quantidade de espaço em branco e pelo menos um dígito) com seguido por 2. Agora significa o que foi capturado dentro da parens \(...\) no regex; no nosso caso, isso é notification_interval\s* .

Essencialmente, isso procura por notification_interval seguido por qualquer quantidade de espaço em branco e, em seguida, um grupo de dígitos e substitui o grupo de dígitos por 2 .

    
por 01.03.2016 / 21:22