-1

I have an xml file called myfile.xml

<!--This is an xml document for test-->
<a><!--This is root node-->
   <b>
     <c>Hi&Welcome</c>
   </b>
   <d>Hello & How are you?</d>
</a>

I want this transformation

<!--This is an xml document for test-->
<a><!--This is root node-->
   <b>
     <c>Hi&amp;Welcome</c>
   </b>
   <d>Hello &amp; How are you?</d>
</a>

I am using sed command as follows to change all occurrences of & into &

sed -i 's:&:&amp;:' myfile.xml

but I am getting `undefined label 'yfile.xml' error. I am unable to proceed further. How to do this?

7
  • 2
    Can't reproduce, works for me. Are you using GNU sed?
    – kos
    Oct 5, 2015 at 13:29
  • Works here. Can't see the problem.
    – A.B.
    Oct 5, 2015 at 13:41
  • @kos - I am using linux
    – jsd
    Oct 5, 2015 at 13:41
  • 1
    Whats the output of sed --version?
    – Nephente
    Oct 5, 2015 at 13:55
  • 1
    That's because you're not using Ubuntu! You are probably on OSX or BSD and sed's -i option needs an argument. Please don't ask about non-Ubuntu OSs here. You can ask on Unix & Linux instead.
    – terdon
    Oct 5, 2015 at 14:00

2 Answers 2

2

If you don't have GNU sed, sed needs an parameter for -i

sed -i.bak 's:&:&amp;:' myfile.xml

and a backup file is a good idea or …

… use Perl ;)

Test with

perl -pe 's/&/&amp;/' myfile.xml

and make an inplace edit with

perl -pi -e 's/&/&amp;/' myfile.xml

But only once.

After the command, the content of myfile.xml is

<!--This is an xml document for test-->
<a><!--This is root node-->
   <b>
     <c>Hi&amp;Welcome</c>
   </b>
   <d>Hello &amp; How are you?</d>
</a>
1
  • Unaccepted? Why? Something wrong? I've added a new part. ;)
    – A.B.
    Oct 5, 2015 at 17:44
-1

You need to escape & because of special character. And you need two passes to complete it.

Use:
1.sed 's|Hi\&|Hi\&amp;|g' yourfile.xml. This will produces:

<!--This is an xml document for test-->
<a><!--This is root node-->
   <b>
     <c>Hi&amp;Welcome</c>
   </b>
   <d>Hello & How are you?</d>
</a>
  1. The second pass will be:sed 's|Hello\ \&| \Hello\ \&amp;|g' test.xml. Produces:

    <!--This is an xml document for test-->
    <a><!--This is root node-->
       <b>
        <c>Hi&amp;Welcome</c>
       </b>
       <d> Hello &amp; How are you?</d>
    </a>
    

    Of course use -i switch to make it permenant.

Another advanced way based on @terdon comment below is:

sed -e 's/Hello &/Hello \&amp;/' -e 's/Hi&/Hi\&amp;/' filename.xml

7
  • 1
    Why would you need two passes? No need for Hi and Hello in the regex.
    – Nephente
    Oct 5, 2015 at 13:53
  • @Nephente, you are also right. There are a lot of way to edit the file using sed or perl or python. Why dont you improve the answer? Good to know others method. Oct 5, 2015 at 13:55
  • You also don't need to escape &. & ins sed's s/// operator means "whatever was matched", so in this particular case, since the OP is matching &, the & on the right hand side will actually be &. There is absolutely no reason to run two passes. In fact, the second pass will break the first and result in Hi&amp;amp;Welcome.
    – terdon
    Oct 5, 2015 at 13:56
  • @terdon, tested on my box. it did not break the first pass. I trying to be more fundamental for the answer, easy to understand in POSIX way. Oct 5, 2015 at 13:58
  • 1
    Oh, sorry, my bad. I hadn't realized that you were using Hello &. No, it won't break on the second pass, it's just not needed. The OP wants to replace & with &amp;, why specify only two specific ones? What if there are others in the file? Also, you still don't need two passes: sed 's/Hello &/Hello \&amp;/;s/Hi&/Hi\&amp;/ or, POSIXLY sed -e 's/Hello &/Hello \&amp;/' -e 's/Hi&/Hi\&amp;/. In both cases though, you don't actually need to escape either the spaces or the & for the reason I explained above.
    – terdon
    Oct 5, 2015 at 14:02

Not the answer you're looking for? Browse other questions tagged .