Convert Comments – Convert C Style Comments to C++ Style Using Sed

sed

I'm trying to convert single line 'C' style comments to 'C++' style. The 'sed' below isn't bad, but of course it fails if any leading code (code before the comment) has any ' / ' in it at all:

sed -i 's,\(^[^\/]*\)\/\*\([^\*]*\)\*\/[ ]*$,\1\/\/\2,' filename

What I wish I could do is this:

... [^\\/\\*] ...

i.e. negate ' /* ' which doesn't work of course, but after several hours of searching, I can't find a simple explanation of how to do that properly 🙁 It doesn't seem like it should be rocket science.

For example, these strings:

blah blah        /* comment */
blah blah / blah /* comment */
blah blah        /* comment */ blah
blah blah / blah /* comment */ blah 

… should convert thusly:

blah blah        // comment 
blah blah / blah // comment 
blah blah        /* comment */ blah  (this CAN'T be converted)
blah blah / blah /* comment */ blah  (this CAN'T be converted)

… obviously no conversion can take place if there is code AFTER the 'C' comment.

I will do a close visual comparison between the file, before and after, so there's no need to handle ' /* ' inside a literal, nor do I want to convert anything multi-line.

Note I think of this as a 'negation' problem but maybe there is another way. I just need to capture everything before a ' /* ' and I don't care how.

FOLLOW UP ON ANSWER BELOW

Well damn! I see that I've completely misunderstood something fundamental:

.*/\*

… reads: "anything except slash star followed by slash star", so actually I get my 'negation' for free 🙂

So, going even further than Barmar:

sed -i 's,^\(.*\)/\*\(.*\)\*/\s*$,\1//\2,' filename

… will even catch this:

blah / * blah        /* co / mme * nt */

and output this:

blah / * blah       // co / mme * nt 

Enlightenment.

Best Answer

Try this:

sed 's,^\(.*\)/\*\([^/]*\)\*/$,\1//\2,'

This won't convert comments that contain embedded / characters. Alternatively, you could use:

sed 's,^\(.*\)/\*\(.*\)\*/$,\1//\2,'

This will do the wrong thing if you have two comments on the same line, e.g.

blah blah        /* comment1 */ blah /* comment2 */

will convert to

blah blah       // comment1 */ blah /* comment2

It might be possible to do better with a PCRE version of sed, as you could then use negative lookahead to test for embedded comments.

Note also that using , as the delimiter in the s command means that you don't have to escape all the / characters in the regexp -- that's the point of using some character other than / as the delimiter when the regexp will contain lots of /.

Related Question