我如何用 sed 或 awk 注释掉两行块(唯一行后跟缩进的非唯一行)?

我如何用 sed 或 awk 注释掉两行块(唯一行后跟缩进的非唯一行)?

我写了以下代码:

#!/usr/bin/bash

wireless_state=$(ip l |grep "3: wlp" |sed -E 's/^.*state ([DOWNUP]{2,4}).*/\1/')
ethernet_state=$(ip l |grep "2: en" |sed -E 's/^.*state ([DOWNUP]{2,4}).*/\1/')

if [[ $ethernet_state == "DOWN" ]]; then
  sed -i 's/^Match Address 192.168.18.109/#Match Address 192.168.18.109/;s/^Match Address 192.168.18.112/#Match Address 192.168.18.112/' sshdc
fi

哪里sshdc有 的副本/etc/ssh/sshd_config。我的尾巴/etc/ssh/sshd_config是这样的:


#Match Address 192.168.18.103 
    #PubkeyAuthentication yes
Match Address 192.168.18.109 
    PubkeyAuthentication yes
#Match Address 192.168.18.111
    #PubkeyAuthentication yes
Match Address 192.168.18.112
    PubkeyAuthentication yes

我希望我的代码注释掉整个两行块,例如

#Match Address 192.168.18.109
#    PubkeyAuthentication yes

而我的代码到目前为止只注释掉了块的第一行,如下所示:

#Match Address 192.168.18.109
    PubkeyAuthentication yes

一行 asMatch Address 192.168.18.109是唯一的,而 while 则PubkeyAuthentication yes不是,并且PubkeyAuthentication no文件头部的某处也有未缩进的行。我如何使用 、 或任何其他 GNU/Linux 实用程序完成此类sed任务awk?请让Python中的解决方案超出这个问题的范围。

答案1

至少对于 GNU sed(GNU/Linux 的默认设置),您可以使用地址范围形式的

addr1,+N

    Matches addr1 and the N lines following addr1.

例如

$ sed '/^Match Address 192\.168\.18\.109/,+1s/^/#/' sshdc
#Match Address 192.168.18.103
    #PubkeyAuthentication yes
#Match Address 192.168.18.109
#    PubkeyAuthentication yes
#Match Address 192.168.18.111
    #PubkeyAuthentication yes
Match Address 192.168.18.112
    PubkeyAuthentication yes

答案2

随着awk使用getline

awk '/^Match/ {$0="#"$0 ; print ; getline ; $0="#"$0 } 1' file

或者通过设置自(去)激活标志:

awk '/^Match/ || b {$0="#$0" ; b=!b } 1' file

答案3

使用sed,您可以匹配该Match行,将输入中的下一行附加到缓冲区,然后在#两行的开头替换为 a :

sed '/^Match Address 192\.168\.18\.109/ { N; s/^/#/; s/\n/&#/; }' file

在这里,将N下一行输入附加到缓冲区,并使用分隔换行符来分隔两行。第一个替换将一个添加#到第一行的开头,而第二个替换将一个添加到下一行的开头。我用来&将换行符重新插入缓冲区,因为使用\n非 GNU插入文字换行符sed是不可能的。

如果该部分的最后/第二行始终包含字符串PubkeyAuthentication,您还可以使用带有单个替换命令的范围地址。

sed '/^Match Address 192\.168\.18\.109/,/PubkeyAuthentication/ s/^/#/' file

/^/如果您希望范围仅运行到下一行,您实际上可以将第二个模式替换为 just :

sed '/^Match Address 192\.168\.18\.109/,/^/ s/^/#/' file

答案4

在每个 Unix 机器上的任何 shell 中使用任何 awk,以下命令将允许您从匹配行开始对任意多行进行更改,只需更改c=2c=37或任何您喜欢的数字:

$ awk '/^Match Address 192\.168\.18\.109/{c=2} c&&c--{$0="#"$0} 1' file
#Match Address 192.168.18.103
    #PubkeyAuthentication yes
#Match Address 192.168.18.109
#    PubkeyAuthentication yes
#Match Address 192.168.18.111
    #PubkeyAuthentication yes
Match Address 192.168.18.112
    PubkeyAuthentication yes

使用 sed-或 awk-a-line-follow-a-matching-pattern 进行打印了解更多信息。

相关内容