我需要更改特定define service
部分中的一个单词 where service_description
isNRPE - NTP_TIME
和 where contact_groups
is 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
没有其他{
s, s ,您可以执行以下操作:}
{...}
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 {...}
,并且替换被解释为代码(感谢标志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
in opsgenie-sla1
that,前面或后面可能有更多以逗号分隔的单词。
或者:
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
}