変更する必要があるdefine service
特定のセクションでは、where service_description
isNRPE - NTP_TIME
とwhere contact_groups
isという1つの単語を変更する必要があり、複数のホストでこれを行う必要があるため、コマンドを使用して作業を短縮したいと思います。以下はファイルの一部です。opsgenie-sla1
opsgenie-sla2
sed
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_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
}