Sed/awk to delete a regex between range of lines

Hi Guys

I am looking for a solution to one problem to remove parentheses in a range of lines.

Input file

module bist_logic_inst(a, ab , dhd, dhdh , djdj, hdh, djjd, jdj, dhd, dhp, dk
);
input a;
input ab;
input dhd;
input djdj;
input dhd;
output hdh;
output djjd;
output jdj;
output dk;
ps(),
ll(),
bist_reverse_mapper Umbist_reverse_inst(  .BIST_SO(), .BIST_SO_ts1(), .BIST_SO_ts2(), .BIST_SO_ts3(), .BIST_GO(), .BIST_GO_ts1(), 
      .BIST_GO_ts2(), .BIST_GO_ts3(), .clk_mbist(), .BIST_SETUP(), .ltest_to_mcp_bounding_en(), 
      .MEM0_BIST_COLLAR_SI(), .MEM1_BIST_COLLAR_SI(), .MEM2_BIST_COLLAR_SI(), .MEM3_BIST_COLLAR_SI(), 
      .bistEn(), .BIST_COLLAR_DIAG_EN(), .ltest_to_en(), .BIST_EVEN_GROUPWRITEENABLE(), 
      .BIST_ODD_GROUPWRITEENABLE(), .BIST_SELECT(), .BIST_WRITEENABLE()
  );

endmodule 

I need to delete the () in the matching regexp : Umbist_reverse_inst and );

Output file

module bist_logic_inst(a, ab , dhd, dhdh , djdj, hdh, djjd, jdj, dhd, dhp, dk
);
input a;
input ab;
input dhd;
input djdj;
input dhd;
output hdh;
output djjd;
output jdj;
output dk;
ps(),
ll(),

bist_reverse_mapper Umbist_reverse_inst( .BIST_SO, .BIST_SO_ts1, .BIST_SO_ts2, .BIST_SO_ts3, .BIST_GO, .BIST_GO_ts1, 
      .BIST_GO_ts2, .BIST_GO_ts3, .clk_mbist, .BIST_SETUP, .ltest_to_mcp_bounding_en, .MEM0_BIST_COLLAR_SI, .MEM1_BIST_COLLAR_SI, .MEM2_BIST_COLLAR_SI, .MEM3_BIST_COLLAR_SI, .bistEn, .BIST_COLLAR_DIAG_EN, .ltest_to_en, .BIST_EVEN_GROUPWRITEENABLE, .BIST_ODD_GROUPWRITEENABLE, .BIST_SELECT, .BIST_WRITEENABLE 
  );

endmodule 

I am trying below code but its not working

awk -v RS=" " '/Umbist_reverse_inst/{sub("()","")}1' list

I suggest using a range expression, so that all replacements occur over all lines. Try:

awk '/Umbist_reverse_inst/,/\);/{gsub(/\(\)/,"")}1' list

Also, the parentheses need to be escaped, since they are special in the an (extended) regular expression.
Plus it is better to use a regex constant ( /.../ ) than a regex string ( " ... " ), otherwise the escape character ( \ ) needs to be escaped itself ( \\ )

--
In the example \); were used as the two characters indicating the last line of the range. If there can be spaces between them, you could use something like \)[ \t]*;

1 Like

A range must span over two (or more) lines.
With a status variable it may end on the same line:

awk '/Umbist_reverse_inst/ {r=1}; r {gsub(/\(\)/,"")}; /\);/ {r=0}; 1' list

If the start pattern is found then set the status variable r . If set then do the replacements. If the end pattern is found then clear the status variable.

1 Like

That is the case with sed , but with awk it can be on the same line.

$ printf '1 2\n2 3\n3 4\n' | sed -n '/1/,/2/p' 
1 2
2 3

$ printf '1 2\n2 3\n3 4\n' | awk '/1/,/2/' 
1 2
2 Likes

Hi
I have tried below code , this is also working

 sed -e '/Umbist_reverse_inst/,/);/ s/()//g' list

Thanks a lot for replying , I am looking for a TCL equivalent for this ,
Can anybody help me on this ?

The sed definitely has the "range must span over two or more lines" problem.
Thanks Scrutinizer for showing that awk does not have this restriction.
Also perl does not have this restriction:

perl -pe '/Umbist_reverse_inst/,/\);/ and s/\(\)//g' list
1 Like