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

Time:09-17

I am trying to replace following pattern

  }

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

with

    tcl_block

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

with the help of sed/awk(preferable sed). But not sure how to consider the content of next line content while searching the pattern.

Please help! BR, Learner!!

CodePudding user response:

This might work for you (GNU sed):

sed '/^\s*}/{:a;N;/\n$/ba;/{\[info exists env(PATH)\]}/!{h;s/\(.*\)\n.*/\1/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}}'

The solution is in two parts.

The first part, replaces a leading } by tcl_block if the next non-empty line contains {[info exists env(PATH)]}.

N.B. If the next non-empty line is does not match it is presented again as a possible match for }.

The second part, on matching {[info exists env(PATH)]}, replaces any occurrences of tcl::native_code by puts in any following lines up to the end of file or an empty line, which ever comes first.


If OP prefers to match from {[info exists env(PATH)]} to a closing } the second part can be simplified:

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

CodePudding user response:

You can try this sed with conditions mentioned in your comments.

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

Output

tcl_block

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

If you have more tcl::native_code lines than the example data, then a complete recode may be needed but to handle it with this current code, add more N; lines to take into account for the substitution within the second condition.

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
  • Related