Idr
Idr

Reputation: 6250

Remove first multiline comment from file

I'm trying to remove all the initial multiline comments from a large directory of source files using unix tools.

For example, I have this file testfile.c

/* 
   testfile.c
   get rid of me
*/

int main(int argc, const char *argv[]) {
/* 
   keep me
*/
    return 0;
}


/* 
   keep me
*/

I've tried using sed like this:

sed '/\/\*/,/\*\//d' testfile.c

but that strips all multiline comments resulting in:

int main(int argc, const char *argv[]) {
    return 0;
}

Is there a way to do this and only remove the multiline comment if it starts at the very first line of the file and to leave all other comments in tact?

Upvotes: 2

Views: 568

Answers (4)

Sadhun
Sadhun

Reputation: 264

sed '/\/\*/,/\*\// s/.*//g' filename | awk '!/^$/'
  1. Matching by pattern ranges and replacing all by nothing.
  2. Removing empty lines

Output:

  int main(int argc, const char *argv[]) {
        return 0;
        }

Upvotes: -1

tomc
tomc

Reputation: 1207

if your comments all end the same way try something like

awk 'BEGIN {while($1 != "*/") getline}{print}'

otherwise you will have to do something fancier looking at the last two chars of a line till you find the end of the first comment.

This has the feature of not testing any line after it has done its job.

Upvotes: 0

jas
jas

Reputation: 10865

This assumes that there's nothing you want from your file before the first multiline comment. It just says to start printing after you see the */ that ends the first comment (and then never to stop again regardless of what's seen).

$ awk '!f&&/\*\//{f=1;next}f' testfile.c 

int main(int argc, const char *argv[]) {
/*
   keep me
*/
    return 0;
}


/*
   keep me
*/

Explanation:

!f && /\*\// { f=1; next }

If the flag f is not set (that is, if f equals 0, which it does when the program begins), and the current line contains the pattern */ (where both characters require escaping with \), then set the flag to 1 and go immediately to the next line (without printing).

f

Print the current line if the flag f is set to 1 (and recall that we only arrive here if the next statement was not executed, thereby avoiding to print the last line of the initial comment).

Upvotes: 4

Cyrus
Cyrus

Reputation: 88646

Wrap your part /\/\*/,/\*\//d with GNU sed in 1,/\*\//{ ... }:

sed '1,/\*\//{ /\/\*/,/\*\//d }' file

Output:


int main(int argc, const char *argv[]) {
/* 
   keep me
*/
    return 0;
}


/* 
   keep me
*/

Upvotes: 2

Related Questions