仅在包含另一个模式的另一行之后的第一次出现中替换包含模式的行
Posted
技术标签:
【中文标题】仅在包含另一个模式的另一行之后的第一次出现中替换包含模式的行【英文标题】:replace a line containing pattern only in the first occurrence after another line that contains another pattern 【发布时间】:2022-01-11 23:47:45 【问题描述】:我想用 sed 替换文件中包含匹配模式 ForwardX11
的行,但只想在包含它的行是在包含另一个模式的另一行之后找到的第一行时替换它。
例子:
Host *
# ForwardAgent no
# ForwardX11 no
# ForwardX11Trusted no
# AnotherLine no
Host localhost
ForwardX11 yes
在上面的示例中,我只想将行 # ForwardX11 no
替换为 Forward yes
,因为此行是行 Host *
之后的第一行。但我想在Host localhost
行之后保持 Forward yes
行不变。
到目前为止,我尝试像这样使用 sed:
sed -i "/ForwardX11Trusted/! s/.*ForwardX11.*/ ForwardX11 yes/" /etc/ssh/ssh_config
但它也改变了第二行(Host localhost 之后的 ForwardX11)。
EDIT 1:假设我不知道包含模式ForwardX11
的行是否在开头有#
,也不知道ForwardX11 是否设置为是或否。
编辑 2:不一定要用 sed 来完成。
【问题讨论】:
's/# ForwardX11 no/ Forward yes/'
我不知道包含模式'ForwardX11'的行是否有#开头,也不知道ForwardX11设置为yes还是no。
【参考方案1】:
使用sed
$ sed -i.bak '/^Host \*/,/ForwardX11/ s/#\?\(.*X11\) no/\1 yes/' /etc/ssh/sshd_config
Host *
# ForwardAgent no
ForwardX11 yes
# ForwardX11Trusted no
# AnotherLine no
Host localhost
ForwardX11 yes
【讨论】:
【参考方案2】:它必须被sed吗?使用 awk 更容易(IMO)
awk '
$1 == "Host" in_block = $2 == "*"
in_block && $2 == "ForwardX11" print " ForwardX11 yes"; next
1
' ssh_config
Host *
# ForwardAgent no
ForwardX11 yes
# ForwardX11Trusted no
# AnotherLine no
Host localhost
ForwardX11 yes
【讨论】:
不,它不必用 sed... 很好的答案以上是关于仅在包含另一个模式的另一行之后的第一次出现中替换包含模式的行的主要内容,如果未能解决你的问题,请参考以下文章
SQL:Regexp_replace 但仅在值第一次出现在记录中时