Alex  Tiger
Alex Tiger

Reputation: 387

Replacing a block of text with indents by sed

I have the next code:

echo -e '  aaa\nddd\nddd\n  bbb' | sed -re ':x; N; $!b x; s/(^|\n)(\s*)(aaa)\n(.*?)\n\2(bbb)(\n|$)/\1\2\3\n\2ccc\n\2\5\6/g'

That code replaces everything between aaa & bbb with ccc. Also it uses the same indents it finds:

fff
   aaa
   ddd
   ddd
   bbb
fff

will be processed to

fff
   aaa
   ccc
   bbb
fff

But there is a problem. I can't port it to use my variables:

sed -ire ":x; N; $!b x; s@(^|\n)(\s*)(${START})\n(.*?)\n\2(${STOPSEQREG})(\n|$)@\1\2\3\n\2${ENUMARRAY[$i]}\n\2\5\6@g" $f

START, STOPSEQREG & ENUMARRAY[i] contain /, *, spaces, :, ;, + and -. Also the array's elements contain \n. The / & * symbols are escaped with \.

The error it shows when running is "Bad backreference".

Can anyone, please, help me?

Thanks in advance.

P.S. Examples of variables:

START: /* R+ Testy */ (with escaped / & *)  
STOPSEQREG: /* R- */ (with escaped / & *)   
ENUARRAY[i]: case AAA:\n    break;  

Upvotes: 1

Views: 576

Answers (1)

declension
declension

Reputation: 4185

A few things I discovered:

  • You need to quote the $s inside your sed script as BASH will probably get there first and interpret them as empty variables. So instead of $!b and (\n|$), try \$!b and (\n|\$).
  • There is potential for simplifying that regex - e.g. can't (.*?) be reduced to (.+)?
  • ...but most importantly, don't use -ire with (GNU) sed. The r is being consumed as an parameter to -i (backup), so your regex is being treated as a basic one, which would need every parenthesis escaped and wouldn't support \s etc. This is why sed sees there as being no captured groups. Use -i -re instead. See the GNU SED manual, and this question too: In-place sed command not working.

General aside: for something this complex, I'd personally always look to a language with decent regex and shell support, e.g. Python / Perl / Ruby / Groovy etc. This avoids the BASH (or other shell) / SED quoting hell quirks and issues, allows unit / integration testing / debugging and logging, but obviously brings its own baggage sometimes, or isn't always possible, unfortunately.

Upvotes: 1

Related Questions