sedを使用して特定のグループの単語を変更するには?

sedを使用して特定のグループの単語を変更するには?

変更する必要があるdefine service特定のセクションでは、where service_descriptionisNRPE - NTP_TIMEとwhere contact_groupsisという1つの単語を変更する必要があり、複数のホストでこれを行う必要があるため、コマンドを使用して作業を短縮したいと思います。以下はファイルの一部です。opsgenie-sla1opsgenie-sla2sed

define service{
        use                             generic-service

        service_description             NRPE
        is_volatile                     0
        check_period                    24x7
        max_check_attempts              3
        check_interval           5
        retry_interval            2
        contact_groups                  opsgenie-sla1

        notification_period             24x7
        check_command                   check_nrpe_port_ssl
        }

    define service{
        use                             generic-service
        host_name                       dns1
        service_description             NRPE - NTP_TIME
        servicegroups                   ntp_checks
        is_volatile                     0
        check_period                    24x7
        max_check_attempts              3
        check_interval           5
        retry_interval            2
        contact_groups                  opsgenie-sla1


        check_command                   check_custom_nrpe!check_ntp_time
        }

答え1

このサービス内にperl他のサービスがないと仮定すると、{次のことができます。}{...}

perl -0777 -pi -e '
  s{^\h*define\h+service\s*\{.*?\}}{
    my $service = $&;
    if ($service =~ m{^\h*service_description\h+NRPE - NTP_TIME\h*$}m) {
      $service =~ s{^\h*contact_groups\h+opsgenie-sla\K1\h*$}{2}gm;
    }
    $service;
  }mges' -- your-file

perl -pはいperlモードsed。を使用して-0777レコード区切り文字を不可能として定義するため、唯一のレコードは完全なファイルです。

次に、一般的な技術を使用して代替を適用します。パターン内で全体が一致define service {...}し、置換がコード(thank you flag e)として解釈されます。これは、一致が正しい場合にのみ連絡先グループを置き換える一致ですservice_description

次に置き換えられますcontact_groups

s{^\h*contact_groups\h+opsgenie-sla\K1\h*$}{2}gm

1<horizontal-spacing-if-any>これはに置き換えられます2

に変更:

s{^\h*contact_groups\h+\K.*}{opsgenie-sla2}gm

たとえば、前の状態に変更しますcontact_groupsopsgenie-sla2

または:

s{^\h*contact_groups\h+(.*,\h*)?opsgenie-sla\K1(?=\h*,|\h*$)}{2}gm

1それに置き換えるには、2前後opsgenie-sla1にカンマ区切りの単語があるかもしれません。

または:

s{^\h*contact_groups\h+(.*,\h*)?\Kopsgenie-sla1(?=\h*,|\h*$)}{opsgenie-sla2}gm

単語全体を置き換えるには、\Kタグ一致Kのept($&)は(?=...)予測演算子であるため、見つかった内容は一致に含まれません。

s{regexp}{replacement}flags m{regexp}flagsこの演算子perldoc -f sについて学び、perldoc -f m正規表現の構文を調べるために使用できますperldoc perlreperldoc perlsyn通貨とオプションの構文について、またはperldoc perlrunで全旅程を開始しますperldoc perl

答え2

これはGNUを使用するソリューションですが、sedファイルの正しいインデントが失われるため、Stéphaneが提供するソリューションを使用することをお勧めします。

sed ':a;N;$!ba;s/\n/ /g' <filename> | sed 's/\(define service{.*service_description\s*NRPE - NTP_TIME.*contact_groups\s.*\)opsgenie-sla1/\1opsgenie-sla2/g'

答え3

POSIX awkを使用してください。

$ cat tst.awk
/define service.*\{/ { prt(); numLines=0 }
{
    lines[++numLines] = $0
    tag = $1
    gsub(/^[[:space:]]*[^[:space:]]+[[:space:]]*|[[:space:]]+$/,"")
    tag2lineNr[tag] = numLines
    tag2val[tag] = $0
}
END { prt() }

function prt(   lineNr) {
    if ( tag2val["service_description"] == "NRPE - NTP_TIME" ) {
        lineNr = tag2lineNr["contact_groups"]
        sub(/opsgenie-sla1/,"opsgenie-sla2",lines[lineNr])
    }
    for ( lineNr=1; lineNr<=numLines; lineNr++ ) {
        print lines[lineNr]
    }
}

$ awk -f tst.awk file
define service{
        use                             generic-service

        service_description             NRPE
        is_volatile                     0
        check_period                    24x7
        max_check_attempts              3
        check_interval           5
        retry_interval            2
        contact_groups                  opsgenie-sla1

        notification_period             24x7
        check_command                   check_nrpe_port_ssl
        }

    define service{
        use                             generic-service
        host_name                       dns1
        service_description             NRPE - NTP_TIME
        servicegroups                   ntp_checks
        is_volatile                     0
        check_period                    24x7
        max_check_attempts              3
        check_interval           5
        retry_interval            2
        contact_groups                  opsgenie-sla2


        check_command                   check_custom_nrpe!check_ntp_time
        }

関連情報