如何使用 sed 搜索和替换命令考虑下一行内容?

How to consider next line content with sed search and replace command?

我正在尝试替换以下模式

  }

  if {[info exists env(PATH)]} {
     tcl::native_code " Message"
     tcl::native_code " Done"

    tcl_block

    if {[info exists env(PATH)]} {
       puts " Message"
       puts " Done"

借助 sed/awk(最好是 sed)。但不确定在搜索模式时如何考虑下一行内容的内容。

请帮忙! BR, 学习者!!

您可以根据评论中提到的条件尝试此 sed

sed '/\}/ {N;N;/if {\[info exists env(PATH)\]} {/ s/\}/tcl_block/};/tcl_block/ {N;N;/tcl/ s/tcl::native_code\|ntcl::native_code/puts/g}' $inputfile

输出

tcl_block

  if {[info exists env(PATH)]} {
     puts  "Message"
     puts  "Done"

如果您的 tcl::native_code 行多于示例数据,则可能需要完整的重新编码,但要使用当前代码处理它,请添加更多 N; 行以考虑在第二个条件内替换。

sed '/\}/ {N;N;/if {\[info exists env(PATH)\]} {/ s/\}/tcl_block/};/tcl_block/ {N;N;N;/tcl/ s/tcl::native_code\|ntcl::native_code/puts/g}' $inputfile

这可能适合您 (GNU sed):

sed '/^\s*}/{:a;N;/\n$/ba;/{\[info exists env(PATH)\]}/!{h;s/\(.*\)\n.*//p;g;s/.*\n/\n/;D};s/}/tcl_block/}' file |
sed '/{\[info exists env(PATH)\]}/{:a;n;/\S/{s/tcl::native_code/puts/g;ba}}'

解决方案分为两部分。

第一部分,如果下一个非空行包含 {[info exists env(PATH)]}.

,则将前导 } 替换为 tcl_block

N.B。如果下一个非空行不匹配,它将再次显示为 }.

的可能匹配项

第二部分,在匹配 {[info exists env(PATH)]} 时,将任何后续行中出现的任何 tcl::native_code 替换为 puts,直到文件末尾或空行,无论哪个出现首先.


如果 OP 更喜欢从 {[info exists env(PATH)]} 匹配到结束 },则可以简化第二部分:

sed '/{\[info exists env(PATH)\]}/,/}/s/tcl::native_code/puts/g'