I'm trying to do some pretty simple sedding of a file:

sed 's:(?<=<Type>)default(?=</Type>):super:' < myfile.xml

The concept's pretty simple, using positive lookaround, find the tags and replace the contents with "super". Unfortunately, it doesn't work, nothing is replaced. What am I doing wrong?

I'm looking to "edit" a file similar to this:


so that it looks like this:

  • Can you clarify the input you have and the output you expect? You know that (, ) and ? have no special meaning in sed if not escaped. – enzotib Nov 10 '11 at 7:57
  • Input: <Type>default</Type>, expected output: <Type>super</Type>. I have to escape my parentheses? Why? – Naftuli Kay Nov 10 '11 at 7:59
  • So why do you put (?<= in the pattern if this is not present in the input? – enzotib Nov 10 '11 at 8:15
  • Positive lookbehind? Make sure that <Type> matches before the expression? – Naftuli Kay Nov 10 '11 at 8:18

Your regular expression is correct, but sed does not handle lookarounds. Your code works fine with perl:

perl -pe 's:(?<=<Type>)default(?=</Type>):super:' your.file

As regular expressions are generally not really good in XML handling, I suggest to try XMLStarlet:

xml ed -O -u '//Type' -v 'super' your.file

Both perl and xml can do in-place editing too, so adds no pain replacing sed.

  • Now I understand what was strange to me in the OP sed script: it uses perl syntax in sed, and I don't know perl. Thanks to clarify. – enzotib Nov 10 '11 at 9:14
  • Thank you! You understood what I was trying to do :) That's EXACTLY what I meant! – Naftuli Kay Nov 10 '11 at 9:27

You're trying to use Perl regular expression syntax in sed; this won't work. Sed uses basic regular expressions; Perl uses extended regular expressions with more features. Lookaround is one of the Perl-specific features; it's found in other modern regexp implementations, but not in sed.

You don't need lookaround here. Positive lookaround at the beginning or end of a pattern you're replacing can easily be turned into a variable replacement text. See also Return only the portion of a line after a matching pattern for more examples and explanations.

sed 's:\(<Type>\)default\(</Type>\):\1super\2:'

Here, since the look-behind and look-ahead are constant, you could even do a simple string replacement.

sed 's:<Type>default</Type>:<Type>super</Type>:'

I do not really understand clearly which parts of the input are variable and which are constant. Supposing Type is variable and default, super are constants, you can use the following sed script


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.