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