从所有* c文件中删除第一个多行注释

时间:2011-11-09 13:35:18

标签: perl shell

我在目录中有很多c文件。每个文件将从如下所示的多行注释开始,并以包含类似

开头
#include<stdio.h>. 

   // This is a c File

   // This File does sampling the frequency

   /* This uses the logic ...
   .....
   .....
   */

#include<stdio.h>

我需要删除所有.c文件开头的所有注释行(如果存在)。有些文件没有这些注释行。在那种情况下,它不应该做任何事情。这应该只删除第一个多行注释。后续的多行注释应该是原样。

如何在perl或shell中执行此操作?

提前致谢

3 个答案:

答案 0 :(得分:1)

如果您确定所有文件都以include开头,则可以在导入之前删除所有行:

perl -i -ne 'print if /^#include/..0' *.c

答案 1 :(得分:0)

#!/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;
}

......或者:

#!/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;
}

...如果您只想对第一个多行注释执行此操作,请将范围的匹配分隔符从花括号更改为“?”字符,读起来像这样:

next while ( m?^\s*/\*?..m?^\s*\*/? );

答案 2 :(得分:0)

我有一个非常简单的解决方案,如果#include可以被视为制服者:

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>

请注意,我必须更改初始#include以便脚本正常工作。对我来说似乎很简单,如果我想要多行注释,最简单的解决方案是使'*/'成为我的记录分隔符,而不是对各行进行大量切换。

但是前瞻,需要缓冲并制定一个更加简洁的解决方案:

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>