如何用sed取消注释下一行

时间:2019-05-01 09:04:17

标签: sed archlinux

在安装带有archiso的Arch时,我试图自动自定义pacman.conf文件。

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

以下是该文件的摘录:

  setPool(i, pool) {
    if(pool === null) return; // prevent that any position gets set back to `null`

    this.setState(({ position }) => {
      if(position[i] !== null) return; // prevent that a pool gets set twice
      return { position: position.map((v, i2) => i === i2 ? pool : v) };
    });
 }

所以我要取消注释multilib块的两行,而不是multilib-testing块!

使用sed可以轻松注释块的第一行:

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

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

但是,下一行与上一个块(实际上是许多其他块)中的下一行完全相同,所以如果我这样做:

sed -i 's/#\[multilib]/\[multilib]/g' /etc/pacman.conf

它将更改所有与模式匹配的行。

我想要的是仅更改[multilib]之后的特定行 我该怎么办?

3 个答案:

答案 0 :(得分:3)

找到#[multilib]行时,请阅读 N ew行并将其附加到模式空间,并删除换行后的#\n )。

sed '/^#\[multilib]/{N;s/\n#/\n/}' file

给出示例输出:

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

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

如果还可以选择

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

这样,您就不必转义正则表达式有效的字符。

答案 1 :(得分:2)

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

/^#\[multilib]/ {   # Match only the [multilib] line.
  n                 # Then read the next line.
  s/^#//            # ... and delete the comment marker.
}

测试:

▶ cat > FILE <<EOF
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist

#[multilib]
#Include = /etc/pacman.d/mirrorlist
EOF
▶ gsed -i '/^#\[multilib]/{n;s/^#//}' FILE

输出:

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

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

答案 2 :(得分:2)

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