Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I am trying to find these three lines:

<!--
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
-->

and replace them with:

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

When I try

sudo sed -i 's:<!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->:<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />:' /myfile.xml

It doesn't find it, I also tried to put \n in it, but it still didn't work:

sudo sed -i 's:<!--\n <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />\n -->:<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />:' /myfile.xml

These don't throw any errors it just doesn't uncomment the line. Any advice would help thanks!

share|improve this question
add comment

3 Answers

up vote 1 down vote accepted

sed reads each line in turn, so it'll never match a multiline pattern unless you nudge it in the right direction. The N command reads one line from the input and appends it to the pattern space.

sed -i -e '/^<!--$/ {
    N; /\n<Connector port="8009" protocol="AJP\/1\.3" redirectPort="8443" \/>$/ {
        N; /\n-->$/ {
            s/^<!--\n//; s/\n-->$//
        }
    }
}' /myfile.xml

Arguably, if you need a command other than s, then you should switch away from sed and to awk or perl. Here's a slightly more flexible Perl snippet that copes with multiline comments in a more general way.

perl -i -pe '
    if (/<!--/) { $_ .= <> while !/-->/;
        s[<!--\n(<Connector port="8009" protocol="AJP/1\.3" redirectPort="8443" />)\n-->][$1];
    }' /myfile.xml
share|improve this answer
    
Thanks for the sed example! –  Doug Molineux May 20 '11 at 22:45
add comment

Sed works on a line-by-line basis. It can be made to work on multiple lines, but it wasn't designed that way - and in my opinion it definitely shows when you attempt to use like that. But if you decide to go that way you will probably have to use registers. Check some of the solutions to http://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n to see how it can be done.

I prefer to use perl instead of sed for this kind of task (multi-line-oriented, I mean). The boilerplate you have to add before the search-and-replace (BEGIN...) is not obvious, but the regex seems cleaner to me:

perl -i.bak -pe 'BEGIN{undef $/;} s/<!--string-->/string/smg' file.xml

Or, using grouping to shorten the expression and to allow you to use a regex there:

perl -i.bak -pe 'BEGIN{undef $/;} s/<!--(string_or_regex)-->/\1/smg' file.xml

It should work both on occurrences with and without newlines between the comment markers and the code to be uncommented.

Adapted from:

http://stackoverflow.com/questions/1030787/multiline-search-replace-with-perl

share|improve this answer
    
Thank you for your help, looks like it's a pain, I decided to use a workaround –  Doug Molineux May 20 '11 at 19:45
add comment

Here's a description of the multiline commands in SED: http://docstore.mik.ua/orelly/unix/sedawk/ch06_01.htm

It's a pain in the butt. You may want to follow Eduardo's advice and use perl -i -p -e instead.

share|improve this answer
    
Thanks for the response! –  Doug Molineux May 20 '11 at 19:45
    
I wouldn't link to unauthorized copies of copyrighted material. –  Mark Wagner May 20 '11 at 19:58
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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