0

I have a string like this in xml file:

&lt;h3&gt;Styled here with: &lt;a href="$url('Product-Show','pid','107723102')$"&gt;FRS blo&lt;/a&gt;, &lt;a href="$url('Product-Show','pid','000482512')$"&gt;Os Cutes&lt;/a&gt;&amp;nbsp;and &lt;a href="$url('Product-Show','pid','000312901')$"&gt;Dor Sho&lt;/a&gt;&lt;/p&gt;</short-description>

I need to replace /p&gt part with /h3&gt.

I tried to do this with the help of sed like below:

sed -i -e 's/&lt;h3&gt;Styled here with\:.*\/p&gt;/&lt;h3&gt;Styled here with\:.*\/h3&gt;/g' new_exp_dev02.xml

but this did not work at all and just doubled the result.

Maybe I forgot to escape some more symbols in order to replace /p&gt part with /h3&gt correctly?

  • bash is a powerful tool, but it's not a text editor; I replaced the tag accordingly. – Jeff Schaller Oct 11 '18 at 16:54
  • I agree but I a have a lot of such strings in xml file where I need to replace tag p. – fuser Oct 11 '18 at 16:56
2

sed can use nearly any character as a delimiter for its expression, I have found it best to not use a delimiter that is in the string one is attempting to replace to limit escaping mistakes.

sed -e 's!/p&gt!/h3\&gt!g' new_exp_dev02.xml would replace /p&gt with /h3&gt. The ampersand (&) in the replacement needs to be escaped as that character has a special meaning in sed replacement expressions.

Your posted sed expression is very hard to read and I am not sure what you are attempting to achieve with it, but it seems to have a different goal then "replace /p&gt part with /h3&gt."

EDIT: if you have to write the expression in that long form, this should work:

sed -e 's!\(&lt;h3&gt;Styled here with:.*\)/p&gt;!\1/h3\&gt;!g' new_exp_dev02.xml

This puts the whole matched part aside from /p&gt into a back reference which we can use in the replacement section as \1. You cannot use regular expression on the replacement side of a sed replacement, as regular expressions are only used for matching.

The first expression in this answer will replace all occurrences of /p&gt with /h3&gt, the second expression will only replace /p&gt if it occurs immediately after matching the regular expression "&lt;h3&gt;Styled here with:.*"

  • thanks @GracefulRestart! indeed & should be escaped. but the approach is still the same I've changed my expression a little bit. Here is ==> sed -i -e 's/\&lt;h3\&gt;Styled here with\:.*\/p\&gt;/\&lt;h3\&gt;Styled here with\:.*\/h3\&gt;/g' new_exp_dev02.xml but again the second part did not work correctly with regular expression and just replaced the left part with Styled here with:.*/h3&gt; and .* left as it was in replaced part instead of changing to the words it should have covered. – fuser Oct 12 '18 at 5:01
  • 1
    Yes - the dot loses its wildcard meaning in the replacement part. If you REALLY need that complicated search pattern, try using "back references". Escaping the & in the regex part is NOT necessary. – RudiC Oct 12 '18 at 10:29
0

You can try with below perl command

 perl -pne "s/p&gt/h3&gt/g" filename

output

&lt;h3&gt;Styled here with: &lt;a href="$url('Product-Show','pid','107723102')$"&gt;FRS blo&lt;/a&gt;, &lt;a href="$url('Product-Show','pid','000482512')$"&gt;Os Cutes&lt;/a&gt;&amp;nbsp;and &lt;a href="$url('Product-Show','pid','000312901')$"&gt;Dor Sho&lt;/a&gt;&lt;/h3&gt;</short-description>

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.