使用linux bash替换文件中两个字符串之间的文本

Kri*_*iss 9 linux bash sed

我有文件"acl.txt"

 192.168.0.1
 192.168.4.5
 #start_exceptions
 192.168.3.34
 192.168.6.78
 #end_exceptions
 192.168.5.55
Run Code Online (Sandbox Code Playgroud)

和另一个文件"例外"

 192.168.88.88
 192.168.76.6
Run Code Online (Sandbox Code Playgroud)

我需要用例外文件的内容替换#start_exceptions和#end_exceptions之间的所有内容.我在这个论坛上尝试了很多解决方案,但没有一个能有效.

Mar*_*ell 14

编辑:

好的,如果你想保留#start和#stop,我将恢复为awk:

awk '
    BEGIN       {p=1}
    /^#start/   {print;system("cat exceptions");p=0}
    /^#end/     {p=1}
    p' acl.txt
Run Code Online (Sandbox Code Playgroud)

感谢@fedorqui在下面的评论中进行调整.

输出:

192.168.0.1
192.168.4.5
#start_exceptions
192.168.88.88
192.168.76.6
#end_exceptions
192.168.5.55
Run Code Online (Sandbox Code Playgroud)

p是一个标志,表示是否打印行.它从头开始为1,所以所有行都被打印,直到找到以#start开头的行.然后我捕捉异常文件的内容并停止打印行,直到找到以#end开头的行,此时我将p标志设置回1,以便打印剩余的行.

如果要输出到文件,请将"> newfile"添加到命令的最后,如下所示:

awk '
    BEGIN       {p=1}
    /^#start/   {print;system("cat exceptions");p=0}
    /^#end/     {p=1}
    p' acl.txt > newfile
Run Code Online (Sandbox Code Playgroud)

如果您真的想要使用SED,那么另一个版本

如果你真的真的想用sed来做,你可以使用嵌套的地址空间,首先选择#start_exceptions和#end_exceptions之间的行,然后再选择其中的第一行以及#end_exceptions行以外的行:

sed '
   /^#start/,/^#end/{
      /^#start/{
         n
         r exceptions
      }
      /^#end/!d
   }
' acl.txt
Run Code Online (Sandbox Code Playgroud)

输出:

192.168.0.1
192.168.4.5
#start_exceptions
192.168.88.88
192.168.76.6
#end_exceptions
192.168.5.55
Run Code Online (Sandbox Code Playgroud)

原始答案

我认为这会奏效:

sed -e '/^#end/r exceptions' -e '/^#start/,/^#end/d' acl.txt
Run Code Online (Sandbox Code Playgroud)

当它找到/ ^ #end /它时会读入例外文件.它还会删除/ #start /和/ #end/之间的所有内容.

为了清楚地表达这种技术,我将匹配略微"松散"了.