Reputation: 387
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
Reputation: 4185
A few things I discovered:
$
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|\$)
.(.*?)
be reduced to (.+)
?-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