sed를 사용하여 특정 그룹의 단어를 변경하는 방법은 무엇입니까?

sed를 사용하여 특정 그룹의 단어를 변경하는 방법은 무엇입니까?

변경해야 하는 define service특정 섹션에서 where service_descriptionis NRPE - NTP_TIME와 where contact_groupsis 라는 단어 하나를 변경해야 하며 , 여러 호스트에서 이 작업을 수행해야 하므로 명령을 사용하여 작업을 단축하고 싶습니다 . 다음은 파일의 일부입니다.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 -pperl모드 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_groups.opsgenie-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 perlre. perldoc 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
        }

관련 정보