Reputation: 767
I have lot of c files in a directory. Each files will start with multi line comment like below and starts with include like
#include<stdio.h>.
// This is a c File
// This File does sampling the frequency
/* This uses the logic ...
.....
.....
*/
#include<stdio.h>
I need to remove all the comments line at the start of all the .c files if they are present. Some files will not have these comment lines. In that case, it should not do anything. This should remove only the first multi line comments. Subsequent multi line comments should be as it is.
How to do this in perl or shell?
Thanks in advance
Upvotes: 0
Views: 471
Reputation: 29854
I had a pretty easy solution, if #include
could be considered a stopper:
use strict;
use warnings;
use English qw<$RS>;
use English qw<@LAST_MATCH_START>;
*::STDIN = *DATA{IO};
my $old_rs = $RS;
local $RS = "*/";
local $_;
while ( <> ) {
if ( m{/[*](?:.(?!:[*]/))*\n(?sm-ix:.(?!:[*]/))*[*]/}m ) {
substr( $_, $LAST_MATCH_START[0] ) = '';
print;
last;
}
print;
last if m/^\s*#include\b/m;
}
$RS = $old_rs;
print while <>;
__DATA__
##include<stdio.h>.
// This is a c File
// This File does sampling the frequency
/* A mline comment not multi */
/* This uses the logic ...
.....
.....
*/
#include<stdio.h>
Notice that I had to change the initial #include
so that the script works. It seemed simple to me that if I wanted multi-line comments, the simplest solution was to make '*/'
my record separator, instead of doing a lot of switching on the individual lines.
But the lookahead, requires buffering and made a messier solution:
use strict;
use warnings;
use English qw<$RS>;
use English qw<@LAST_MATCH_START>;
*::STDIN = *DATA{IO};
my $old_rs = $RS;
local $RS = "*/";
local $_;
my ( $rin, $rie );
my $mline = '';
my $buffer;
while ( <> ) {
if ( m{/[*](?:.(?!:[*]/))*\n(?sm-ix:.(?!:[*]/))*[*]/}m ) {
my $split = $LAST_MATCH_START[0];
print substr( $_, 0, $split );
$mline = substr( $_, $split );
last;
}
print;
}
$RS = $old_rs;
while ( <> ) {
$buffer .= $_;
if ( /^\s*#include\b/ ) {
$mline = '';
last;
}
}
print $mline, $buffer;
print while <>;
__DATA__
#include<stdio.h>.
// This is a c File
// This File does sampling the frequency
/* A mutli-line comment not on multiple lines */
/* This uses the logic ...
.....
.....
*/
#include<stdio.h>
Upvotes: 0
Reputation: 7526
#!/usr/bin/env perl
use strict;
use warnings;
my $skipping = 0;
while (<>) {
m{^\s*//} and next;
m{^\s*/\*.*\*/\s*$} and next;
if ( m{^\s*/\*} ) {
$skipping = 1;
next;
}
if ( m{^\s*\*/} ) {
$skipping = 0;
next;
}
next if $skipping;
print;
}
...or alternatively:
#!/usr/bin/env perl
use strict;
use warnings;
while (<>) {
next if m{^\s*//};
next if m{^\s*/\*.*\*/\s*$};
next while ( m{^\s*/\*}..m{^\s*\*/} );
print;
}
...AND if you only want to do this for the first multi-line comment, change the match delimiters of the range from curly braces to the "?" character, to read like this:
next while ( m?^\s*/\*?..m?^\s*\*/? );
Upvotes: 0
Reputation: 2603
If you are sure that all files start with an include, you could remove all lines before the import:
perl -i -ne 'print if /^#include/..0' *.c
Upvotes: 1