[英]How to use sed to search and replace a pattern who appears multiple times in the same line?
[英]Perl/Sed command to replace same pattern multiple times
我需要使用perl或sed等命令在/etc/xinetd.d/chargen
设置disable=no
。
/etc/xinetd.d/chargen
内容是:
# description: An xinetd internal service which generate characters. The
# xinetd internal service which continuously generates characters until the
# connection is dropped. The characters look something like this:
# !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefg
# This is the tcp version.
service chargen
{
disable = yes
type = INTERNAL
id = chargen-stream
socket_type = stream
protocol = tcp
user = root
wait = no
}
# This is the udp version.
service chargen
{
disable = yes
type = INTERNAL
id = chargen-dgram
socket_type = dgram
protocol = udp
user = root
wait = yes
}
我用过perl命令
perl -0777 -pe 's|(service chargen[^\^]+)disable\s+=\syes|\1disable=no|' /etc/xinetd.d/chargen
但它只在一个地方取代。
# description: An xinetd internal service which generate characters. The # xinetd internal service which continuously generates characters until the # connection is dropped. The characters look something like this: # !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefg # This is the tcp version. service chargen { disable = yes type = INTERNAL id = chargen-stream socket_type = stream protocol = tcp user = root wait = no } # This is the udp version. service chargen { disable=no type = INTERNAL id = chargen-dgram socket_type = dgram protocol = udp user = root wait = yes }
什么是让它在两个地方都有效的正确命令?
注意 :我可以用disable = no
替换disable = yes
而不匹配service chargen
但是我需要在/etc/xinetd.conf
使用相同的sed / perl命令来替换其他服务。
更新正如Jonathan在评论中强调的那样,禁用可以位于花括号内的任何位置。
使用sed
,您可以使用:
sed -e '/^service chargen/,/^}/ { /disable *= yes/ s/yes/no/; }'
第一部分搜索从一个起始service chargen
到第一行的行的范围,然后以}
开头; 在该范围内时,它查找包含线disable = yes
与之间的空间任意数disable
和= yes
,和改变yes
对no
。 如果有必要,你可以使正则表达式更繁琐(没有尾随空格;不编辑service chargen2018
块,要求}
没有尾随空白等)但它可能没有必要。
您通常可以进行就地编辑,但要注意系统之间在如何执行此操作的语义上的差异。 (BSD和macOS需要-i ''
; GNU只需要-i
;两者都接受-i.bak
,两者意味着相同 - 但你有一个备份文件要清理。)
您可以使用此perl
命令:
perl -0777 -pe 's/(?m)^service chargen\s*\{[^}]*disable\s*=\s*\Kyes/no/g' file
# description: An xinetd internal service which generate characters. The
# xinetd internal service which continuously generates characters until the
# connection is dropped. The characters look something like this:
# !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefg
# This is the tcp version.
service chargen
{
disable = no
type = INTERNAL
id = chargen-stream
socket_type = stream
protocol = tcp
user = root
wait = no
}
# This is the udp version.
service chargen
{
disable = no
type = INTERNAL
id = chargen-dgram
socket_type = dgram
protocol = udp
user = root
wait = yes
}
\\K
重置报告的匹配的起点。 最终匹配中不再包含任何先前消费的字符
awk好吗?:
$ awk '/service chargen/,/}/{if(/disable/)sub(/yes/,"no")}1' file
...
disable = no
...
disable = no
...
解释:
$ awk ' # well, awk
/service chargen/,/}/ { # between service chargen {...}
if(/disable/) # if disable found
sub(/yes/,"no") # replace yes with no
}1' file # output
您可以根据自己的喜好调整正则表达式( /disable/
)(例如/^ *disable *=/
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.