【问题标题】: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。

标签: bash sed


【解决方案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... 很好的答案
    猜你喜欢
    • 2016-01-20
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    • 2013-06-07
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多