删除文本文件中多行字符串的第一个字符

删除文本文件中多行字符串的第一个字符

我正在自动化 Ubuntu 20.04 VM 的构建过程。 Ubuntu 20.04 似乎默认禁用了 bash-completion。我想在构建时默认启用此功能。我使用的生命周期管理系统允许我在虚拟机完全启动之前运行一些最终命令。我需要的是通过 为所有用户启用 bash-completion /etc/bash.bashrc

目前,构建的机器/etc/bash.bashrc如下所示:

# System-wide .bashrc file for interactive bash(1) shells.

...

# enable bash completion in interactive shells
#if ! shopt -oq posix; then
#  if [ -f /usr/share/bash-completion/bash_completion ]; then
#    . /usr/share/bash-completion/bash_completion
#  elif [ -f /etc/bash_completion ]; then
#    . /etc/bash_completion
#  fi
#fi

...

EOF

我想删除#该行之后的每个字符# enable bash completion in interactive shells。结果应该是:

# System-wide .bashrc file for interactive bash(1) shells.

...

# enable bash completion in interactive shells
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

...

EOF

我尝试编写一个sed命令,但没有成功。任何想法,将不胜感激。谢谢!

答案1

下面的代码将从#后面的行中删除行开头的所有 s ,直到# enable bash completion in interactive shells以 开头的最后一个连续行#

$ awk '
    f && !sub(/^#/,"") { f=0 }
    $0 == "# enable bash completion in interactive shells" { f=1 }
1' file
# System-wide .bashrc file for interactive bash(1) shells.

...

# enable bash completion in interactive shells
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

...

EOF

答案2

尝试这样的事情:

sed -i -e '/^# enable bash completion/,/^#fi/ {
             s/^#//;
             s/^ enable bash completion/#&/;
           }' /etc/bash.bashrc

#这将从以 开头的行# enable bash completion到以 开头的下一行的所有行中删除前导#fi,然后将后缀放在行#的开头enable bash ...

答案3

使用awk

以下将从#第五条记录之后的记录开始处删除。

awk 'NR>5{sub(/^#/,"");}1' input

或者

awk 'NR==1,/^# enable/{print;next}{sub(/^#/,"");print }' input

NR==1,/^# enable/{print;next}从第一条记录打印到以 开头的记录# enable。该next声明意味着不会对这些记录采取进一步行动。

然后sub()函数#从记录的开头删除。

另一种方法:这是在awk中描述的答案由@cas。

awk '/^# enable/,/^#fi/
{if (/^# enable/) ; else sub(/^#/,"")}1' input

答案4

sed -n -e '
 /^# enable bash completion/{
  h 
  :a {
   n
   /^#fi$/!{
    H 
    ba
   }
  }
  g
  s/#//g
  s/.*/#&\nfi/
 }
 p
' data

如果我们获得该部分,则将该行保存在保留空间中bash completion,并将每一行附加到保留空间中,直到到达最后一个fi。此时获取保留空间的内容并:1)删除所有#,2)将 a 放在#前面enable bash completion ...并将final附加fi到块中。

添加-i选项以允许sed对文件本身进行更改:sed -n -i -e 'the previous sed command'

相关内容