Regex 修改模式匹配行以及文件中的下一行

Regex 修改模式匹配行以及文件中的下一行,regex,awk,sed,Regex,Awk,Sed,我正在尝试编写一个脚本,其中包括自动启用multilib。这意味着在我的/etc/pacman.conf文件中,我必须把这个 #[multilib] #Include = /etc/pacman.d/mirrorlist 进入这个 [multilib] Include = /etc/pacman.d/mirrorlist 不会意外地从这样的行中删除# #[community-testing] #Include = /etc/pacman.d/mirrorlist 我已经通过使用这个代码完成

我正在尝试编写一个脚本,其中包括自动启用
multilib
。这意味着在我的
/etc/pacman.conf
文件中,我必须把这个

#[multilib]
#Include = /etc/pacman.d/mirrorlist
进入这个

[multilib]
Include = /etc/pacman.d/mirrorlist
不会意外地从这样的行中删除
#

#[community-testing]
#Include = /etc/pacman.d/mirrorlist
我已经通过使用这个代码完成了这项工作

linenum=$(rg -n '\[multilib\]' /etc/pacman.conf | cut -f1 -d:)
sed -i "$((linenum))s/#//" /etc/pacman.conf
sed -i "$((linenum+1))s/#//" /etc/pacman.conf

但是我想知道,这是否可以在没有任何数学表达式的情况下在一行代码中解决。

请尝试以下内容,仅使用显示的示例编写。考虑到
multilib
,这正是您想要处理的下一行

awk '
/multilib/ || found{
  found=$0~/multilib/?1:""
  sub(/^#+/,"")
  print
}
' Input_file
说明:

首先检查一行是否包含
multilib
或变量found已设置,然后按照其块内的说明进行操作

内部块检查行是否有multilib,然后将其设置为1或将其置零。因此,只有multilib之后的下一行才被处理

使用awk的子函数将一个或多个出现的起始哈希替换为NULL。 然后打印当前行。

一行:

perl -0777 -api.back -e 's/#(\[multilib]\R)#/$1/' /etc/pacman.conf

如果只有一个
[multilib]
条目,使用
ed
和shell的
printf

printf'/^\[multilib\]$/+1s/^#/\n,p\nQ\n'| ed-s/etc/pacman.conf
  • Q
    更改为
    w
    以编辑pacman.conf

  • 匹配
    #[multilib]

  • 包括下一个地址

  • +1
    下一行(加上下面的一行)

  • s/^#/
    删除前导的
    #

  • ,p
    将所有内容打印到
    stdout

  • Q
    exit/quit
    ed
    无错误信息

  • -s
    表示不打印任何消息


    • 使用GNU。查找以
      #[multilib]
      开头的行,将下一行(
      N
      )追加到模式空间,然后从模式空间(
      s/#/g
      )中删除所有
      #

      如果这两行包含更多的
      #
      ,则这些也将被删除。

      Ed可以这样做

      cat >> edjoin.txt << EOF
      /multilib/;+j
      s/#//
      s/#/\
      /
      wq
      EOF
      
      ed -s pacman.conf < edjoin.txt
      rm -v ./edjoin.txt
      

      cat>>edjoin.txt这将在每个UNIX设备上的任何shell中使用任何awk:

      $ awk '$0 == "#[multilib]"{c=2} c&&c--{sub(/^#/,"")} 1' file
      [multilib]
      Include = /etc/pacman.d/mirrorlist
      
      如果必须取消注释500行而不是2行,那么只需将
      c=2
      更改为
      c=500
      (而不是像当前接受的解决方案那样键入
      N
      500次)。请注意,您也不必转义要匹配的字符串中的任何字符。因此,除了健壮性和可移植性之外,这是一个比目前为止您拥有的其他解决方案更普遍有用的习惯用法。有关更多信息,请参阅。

      这可能适合您(GNU-sed):

      关注第一行开始的一系列行(在本例中为两行),如果第一行是
      #[multilib]
      ,则删除这些行中的第一个字符

      注意:
      [
      ]
      必须在regexp中转义,否则它们将匹配单个字符,即
      m
      u
      l
      t
      i
      B
      。如果要取消注释
      n
      行和匹配行,可以通过将整数
      +1
      更改为
      +n
      来扩展范围

      要删除
      [multilib]
      部分中的所有注释,请执行以下操作:

         sed '/^#\?\[[^]]*\]$/h;G;/^#\[multilib\]/M s/^#//;P;d' file
      

      在使用GNU sed时,我认为这是所有回答中最容易理解的,并且只想删除第一个
      ,如果它开始于
      sed-i'/^\[multilib\]/{N;s/^\//mg}文件
      sed '/^#\[multilib\]/,+1 s/^#//' file
      
         sed '/^#\?\[[^]]*\]$/h;G;/^#\[multilib\]/M s/^#//;P;d' file