10

I am trying to write a script that will delete all comments and everything in between inside C files in my current directory. I've been using sed, and this is what I have so far:

sed -i '/ * [^()] */d' *.c

This works when the comments are on the same line as an asterisk or backslash.

However it doesn't work when there is a commented line without a slash or asterisk.

I know sed goes line by line, I just don't know how to tell it to keep deleting until it sees a */.

jasonwryan
  • 73,126
Dawn
  • 101

2 Answers2

9

Removing comments without using a real C-preprocessor is not exactly trivial. I once came up with something like this:

perl -0777 -pe'
 s{
     /\*.*?\*/
   | //[^\n]*
   | (
        "(?:\\.|.)*?"
      | '\''(?:\\.)?.*?'\''
      | \?\?'\''
      | .[^'\''"/]*
     )
  }{if ($1eq""){" "}else{$1}}exsg' 

Which should cover most cases like things like:

printf("%c%c%s", '"' /* d-quote */, '\'', "/*" "*/");

See the interesting discussion there for more details.

4

If this doesn't have to be done in sed, then you can do it easily with perl:

perl -p0i -e 's#/\*.*?\*/##sg' *.c

Note that this will delete parts of quoted strings that are not meant to be comments at all as in the example in the comments below.

Joseph R.
  • 39,549
  • 3
    This fails pretty spectacularly. Try this: echo 'printf("Comments in C are written /* like this */.\n");' | perl -p0i -e 's#/\*.*?\*/##sg' – user Apr 15 '13 at 13:59
  • Good point. This code does not make provisions for the case when block comments occur inside quoted text. Editing answer. – Joseph R. Apr 15 '13 at 15:39
  • I voted your answer, although it does not cover twisted cases. using the non-greedy regex .*? is a smart trick and does the job trick for 90% of cases – Muayyad Alsadi Apr 15 '13 at 18:15