I'm having trouble with a backreference in my replacement text that is followed by a literal. I have tried the following:
perl -0pi -e "s/(<tag1>foo<\/tag1>\n\s*<tag2>)[^\n]*(<\/tag2>)/\1${varWithLeadingNumber}\2/" file.xml
perl -0pi -e "s/(<tag1>foo<\/tag1>\n\s*<tag2>)[^\n]*(<\/tag2>)/\g{1}${varWithLeadingNumber}\g{2}/" file.xml
The first of course causes problems because ${varWithLeadingNumber} begins with a number, but I thought the \g{1}
construct in my second attempt above was supposed to solve this problem. I'm using perl 5.12.4.
Using \1
, \2
, etc in the replacement expression is wrong. \1
is a regular expression pattern that means "match what the first capture matched" which makes no sense in a replacement expression. Regular expression patterns should not be used outside of regular expressions! $1
, $2
, etc is what you should be using there.
After fixing \1
, you have
perl ... -e'... s/.../...$1$varWithLeadingNumber.../ ...'
That said, I think varWithLeadingNumber
is supposed to be a shell variable? You shouldn't have any problems if it's a Perl variable. If you're having the shell interpolate varWithLeadingNumber
, the problem can be fixed using
perl ... -e"... s/.../...\${1}${varWithLeadingNumber}.../ ..."
Note that you will have problems if $varWithLeadingNumber contains "$", "@", "\" or "/", so you might want to use a command line argument instead of interpolation.
perl ... -pe'
BEGIN { $val = shift; }
... s/.../...$1$val.../ ...
' "${varWithLeadingNumber}"
You could also use an environment variable.
export varWithLeadingNumber
perl ... -pe's/.../...$1$ENV{varWithLeadingNumber}.../'
or
varWithLeadingNumber=varWithLeadingNumber \
perl ... -pe's/.../...$1$ENV{varWithLeadingNumber}.../'
If you did have a \1
s/...\1.../.../
you can avoid the problem a number of ways including
s/...(?:\1).../.../
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With