sed跨行匹配替换

详情参考这里

有文本 test.txt
123
456kaishi33333
ddd
jieshu66666
ddd
444444

想把从kaishi到jieshu中的内容一次替换为COMMENT

sed -e "{:begin;  /jieshu/! { $! { N; b begin }; }; s/kaishi.*jieshu/COMMENT/; };" test.txt

执行后的内容为:

123
456COMMENT66666
ddd
444444

大括号里应该是用了sed语法编程

  • :begin,这是一个标号,man中叫做label,也就是跳转标记,供b和t命令用,本例中使用了b命令。

  • /jieshu/!是要替换内容的结束标记,带上!就是说当一行处理完毕之后,如果没有发现结束标记就继续,jieshu就是你要结束的搜索词

  • $!,$在正则中表示字符串结尾,在sed中代表文件的最后一行,本句和上一句结合起来的意思就是:如果在本行没有发现结束标记,并且当前扫描过的行并不是文件的最后一行。

  • N;,把下一行的内容追加(append)到缓冲区(pattern)之后,在我们的例子中,在处理456kaishi33333这一行的内容时,就会执行到这里,然后把下一行的内容ddd,依次类推把
    jieshu66666一起放入缓冲区,相当于“合并”成了一行(sed的缓冲区中默认都只会包含一行的内容)。

  • b begin,由于仍然没有找到结束标记jieshu(注意上一条说的缓冲区还没有被处理),所以在这里跳回到标号begin,重新开始命令。如果开始和结束标记之间间隔了多行,那么就会有多次跳转发生。

  • s/kaishi.*jieshu/COMMENT/;,终于,/jieshu/!不再匹配成功,也就是我们已经找到了结束标记,那么用s命令来进行替换。如果开始和结束标记在一行的话,就会越过上面那些复杂的处理,直接执行到这里了。

posted @ 2021-07-30 10:48  一个小学僧  阅读(818)  评论(0编辑  收藏  举报