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.
/*
? Just capture everything before/*
. – Barmar Oct 22 '14 at 19:25/* */
comments? What about literal strings that happen to contain"... /* ..."
? – Greg Hewgill Oct 22 '14 at 19:27/*
can be in strings, but are not comments. etc. This question is asked regularly, unfortunately I can not remember where. The answers will tell you that regexps can not do it alone. Therefore you will need something more powerful such asawk
. – ctrl-alt-delor Oct 22 '14 at 19:33cout<<"a"<<endl; /* foo */ cout<<"b"<<endl;
. – jimmij Oct 22 '14 at 19:36.*/\*
does not read anything except `/*, but rather *anything except **the last
/`*. it will happily match as many intervening `/'s as you could want to provide it. this
[^/*]*/*is anything except
/or
then
/`. – mikeserv Oct 23 '14 at 08:30/*
is the way to go, then youre good to go, because.*/\*
will get the last every time. i just wanted to make it clear that it will gobble any preceding occurrences. – mikeserv Oct 23 '14 at 16:00