如何使用sed取消注释下一行

如何使用sed取消注释下一行,sed,archlinux,awk,Sed,Archlinux,Awk,我试图在使用archiso安装Arch时自动自定义pacman.conf文件 为此,我想取消对pacman配置文件中两行的注释 以下是有关文件的摘录: #[multilib-testing] #Include = /etc/pacman.d/mirrorlist #[multilib] #Include = /etc/pacman.d/mirrorlist 所以我想取消对multilib块的两行的注释,但不想取消multilib测试块的注释 要取消注释块的第一行,使用sed很容易: sed

我试图在使用archiso安装Arch时自动自定义pacman.conf文件

为此,我想取消对pacman配置文件中两行的注释

以下是有关文件的摘录:

#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist

#[multilib]
#Include = /etc/pacman.d/mirrorlist
所以我想取消对multilib块的两行的注释,但不想取消multilib测试块的注释

要取消注释块的第一行,使用sed很容易:

sed -i 's/#\[multilib]/\[multilib]/g' /etc/pacman.conf
但是,下一行与前一块中的行以及实践中的许多其他块中的行完全相同,因此如果我这样做:

sed -i 's/#Include =/Include =/g' pacman.conf
它将改变所有与图案匹配的线条

我只想在[multilib]之后更改特定的行 如何才能做到这一点?

当您找到[multilib]行时,请读取新行并将其附加到模式空间,然后删除换行符后面的内容\n

考虑到您的样本的输出:

#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist

#[multilib]
Include = /etc/pacman.d/mirrorlist
如果也是一种选择:

awk 'f{sub(/^#/,"");f=0} $0=="#[multilib]"{f=1} 1' file
这样,您就不需要转义正则表达式活动字符。

当您找到[multilib]行时,读取新行并将其附加到模式空间,然后删除换行符后面的字符。\n

考虑到您的样本的输出:

#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist

#[multilib]
Include = /etc/pacman.d/mirrorlist
如果也是一种选择:

awk 'f{sub(/^#/,"");f=0} $0=="#[multilib]"{f=1} 1' file

这样,您就不需要转义正则表达式活动字符。

有一个更简单的sed解决方案,不需要任何多行技术:

/^\[multilib]/{仅匹配[multilib]行。 n然后读下一行。 并删除注释标记。 } 测试:


▶ cat>FILE有一个更简单的sed解决方案,它不需要任何多行技术:

/^\[multilib]/{仅匹配[multilib]行。 n然后读下一行。 并删除注释标记。 } 测试:


▶ cat>FILEsed用于对单个字符串执行s/old/new操作,仅此而已。使用awk:

$ awk '$0=="#[multilib]"{c=2} c&&c--{sub(/#/,"")} 1' file
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist

[multilib]
Include = /etc/pacman.d/mirrorlist
不需要转义字符,如果需要从50行而不是2行中删除,只需将2更改为50,就不必重写脚本!如果愿意,您显然可以参数化开始字符串和要取消注释的行数:

$ awk -v beg='#[multilib]' -v num=2 '$0==beg{c=num} c&&c--{sub(/#/,"")} 1' file
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist

[multilib]
Include = /etc/pacman.d/mirrorlist

$ awk -v beg='#[multilib-testing]' -v num=2 '$0==beg{c=num} c&&c--{sub(/#/,"")} 1' file
[multilib-testing]
Include = /etc/pacman.d/mirrorlist

#[multilib]
#Include = /etc/pacman.d/mirrorlist

$ awk -v beg='#[multilib-testing]' -v num=5 '$0==beg{c=num} c&&c--{sub(/#/,"")} 1' file
[multilib-testing]
Include = /etc/pacman.d/mirrorlist

[multilib]
Include = /etc/pacman.d/mirrorlist

sed用于对单个字符串执行s/old/new操作,仅此而已。使用awk:

$ awk '$0=="#[multilib]"{c=2} c&&c--{sub(/#/,"")} 1' file
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist

[multilib]
Include = /etc/pacman.d/mirrorlist
不需要转义字符,如果需要从50行而不是2行中删除,只需将2更改为50,就不必重写脚本!如果愿意,您显然可以参数化开始字符串和要取消注释的行数:

$ awk -v beg='#[multilib]' -v num=2 '$0==beg{c=num} c&&c--{sub(/#/,"")} 1' file
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist

[multilib]
Include = /etc/pacman.d/mirrorlist

$ awk -v beg='#[multilib-testing]' -v num=2 '$0==beg{c=num} c&&c--{sub(/#/,"")} 1' file
[multilib-testing]
Include = /etc/pacman.d/mirrorlist

#[multilib]
#Include = /etc/pacman.d/mirrorlist

$ awk -v beg='#[multilib-testing]' -v num=5 '$0==beg{c=num} c&&c--{sub(/#/,"")} 1' file
[multilib-testing]
Include = /etc/pacman.d/mirrorlist

[multilib]
Include = /etc/pacman.d/mirrorlist

鉴于OP的明显需求,AWK解决方案的额外复杂性是使用sed的有力理由。也就是说,我总是喜欢阅读和思考你们优雅的AWK解决方案。有多复杂?这是一个惯用的解决方案,适用于每一种情况,在这种情况下,您需要从某个条件开始对某些行执行某些操作,并且它可以在任何UNIX机器上的任何shell中的任何awk中工作。在任何情况下,只要使用AWG的强实参行数,就可以将其应用于任何后续操作的强实参行数。也就是说,我总是喜欢阅读和思考你们优雅的AWK解决方案。有多复杂?这是一个惯用的解决方案,适用于每一种情况,在这种情况下,您需要从某个条件开始对某些行执行某些操作,并且它可以在任何UNIX机器上的任何shell中的任何awk中工作。这只是习惯用法g,一旦您知道了它,您就可以将它应用于任何类似的情况,以处理任何影响后续行数和任何所需操作的条件。