asad
asad

Reputation: 33

Unable to remove multliline comments using sed

In a file sedd:

/* This program read two integer numbers from the
   keyboard and prints their product.
                written by:
                Date:
*/

/*              statements */
  scanf ("%d",&number1);
  scanf ("%d",&number2);
  result = number1 * number2;
  printf ("%d",result);
  return 0;
} /* main */

Command:

sed -f sedd.sed sedd 

where sedd.sed is:

/^\/\*/,/^\*\/$/{ d
}

desired output

  scanf ("%d",&number1);
  scanf ("%d",&number2);
  result = number1 * number2;
  printf ("%d",result);
  return 0;
}

I used sedd.sed as

$a\
\}

/^\/\*/,5{
d
}

/^\/\*.*\*\//d
/\/\*.*\*\//d

I'm not understanding why (below) breaks the code? The range with regex is not moving the pattern space forward I believe.

/^\/\*/,/^\*\/$/{ d
}

Upvotes: 0

Views: 36

Answers (2)

Jonathan Leffler
Jonathan Leffler

Reputation: 755006

I'm not clear why you want to add a } at the end, so this script doesn't, but you can easily add it back into your script.

This script is not a generic C comment parser. But it does deal with your input (but not mine):

s%/\*.*\*/% %g
/^\/\*/,/^\*\/$/ d

The first line more or less deals with single-line comments, as long as they aren't too complex (such as being embedded inside a string literal, or a multi-character constant, or there are several such comments on a single line). The second is your original multiline comment parser. It is OK within its constraints, one of which is that it doesn't attempt to detect general comments — only those starting in column 1 and finishing in a comment end marker as the whole of another line.

For this extended version of your input:

blurble
flup
/* This program read two integer numbers from the
   keyboard and prints their product.
                written by:
                Date:
*/
fangdoodle
wotsit

/* This program read two integer numbers from the
   keyboard and prints their product.
                written by:
                Date:
*/

int main(void)
{

/*              statements */
  scanf ("%d",&number1);
  scanf ("%d",&number2);
  result = number1 * number2;
  printf ("%d",result);
  return 0;
} /* main */

char /*far*/*deviousness(/*const*/ char *str)
{
    enum { MASSIVE = 128 };
    char *result = malloc(MASSIVE);
    char cmp[] = "/* not a comment */";
    for (int i = '/*'; i < '*/'; i++)
        printf("%d\n", i);  /* Note
                                this is not deleted */
    snprintf(result, MASSIVE, "%s%s%s %s", "/*", str, "*/", cmp);
    return result;
}

/*
 * This style of comment
 * is not handled properly.
 */
char *maliciously(char *deleted)
{
    return deleted + 4;
}

/* Oh why?
*/

whooptido!

The output is:

blurble
flup
fangdoodle
wotsit


int main(void)
{


  scanf ("%d",&number1);
  scanf ("%d",&number2);
  result = number1 * number2;
  printf ("%d",result);
  return 0;
}  

char   char *str)
{
    enum { MASSIVE = 128 };
    char *result = malloc(MASSIVE);
    char cmp[] = " ";
    for (int i = ' '; i++)
        printf("%d\n", i);  /* Note
                                this is not deleted */
    snprintf(result, MASSIVE, "%s%s%s %s", " ", cmp);
    return result;
}


whooptido!

Trying to eliminate C style comments precisely using sed is very, very hard. You can more or less handle it for simple cases, but doing the job properly, recognizing strings and characters etc, is very tough. And that's before you get into evil comments like:

/\
\
* This *\
\
/  /??/
* Trigraphs are going to go from C++17 *??/
??/
/

Pity the poor compiler writer who has to ensure that their compiler does handle such nonsense properly.

Upvotes: 0

Cyrus
Cyrus

Reputation: 88939

Try this:

sed '/^\/\*/,/^\*\//d' file

If you want to edit your file with GNU sed "in place" add option -i.

Upvotes: 1

Related Questions