2016-01-23 58 views
2

我试图使用unix工具从源文件的大目录中删除所有最初的多行注释。从文件中删除第一个多行注释

例如,我有这个文件testfile.c

/* 
    testfile.c 
    get rid of me 
*/ 

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


/* 
    keep me 
*/ 

我已经试过用的sed是这样的:

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

但剥离导致所有多行注释:

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

有没有办法做到这一点,只有删除多行注释,如果它开始在非常该文件的第一行,并保留所有其他评论的机智?

+0

你删除的许可证? – tomc

+0

是的,计划在完成后将它们放回 – Idr

+0

'^'是起始处发生匹配模式的锚标签。所以像这样使用它'/^\/\ * /,/ \ * \ // d' – 2016-01-23 20:00:03

回答

4

这假定在第一个多行注释前没有你想要的文件。它只是说,在看到*/结束了第一条评论(然后再也不会停止,无论看到什么)后开始打印。

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

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


/* 
    keep me 
*/ 

说明:

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

如果标志f未设置(即,如果f等于0,在程序开始时它),以及当前行包含图案*/(其中两个字符都需要用\转义),然后将标志设置为1并立即转到下一行(不打印)。

f 

打印当前行如果标志f设置为1(和回忆,如果是没有执行next声明,我们只来到这里,从而避免了打印的初始注释的最后一行)。

+0

谢谢!你能解释一下这种魔法吗? – Idr

+0

不客气,补充说明---如果还有什么不清楚的话请告诉我。 – jas

+1

更简洁:'awk'f;/* \ // {f = 1}'testfile.c'。 –

0

如果您的意见都最终以同样的方式 尝试像

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

,否则你将不得不做一些票友看着行的最后两个字符,直到你找到的第一个注释的结尾。

这具有在完成任务后不测试任何行的功能。

+0

如果'getline'失败,会出现其他问题,并且完全不必要使用'getline',这将分解为无限循环。请参阅http://awk.info/?tip/getline' –

2

与GNU在1,/\*\//{ ... } sed的包裹你的一部分/\/\*/,/\*\//d

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

输出:

 

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


/* 
    keep me 
*/ 
+0

这也适用。你能解释一下你添加的'1'部分吗? – Idr

+0

'1,/ \ * \ // {...}'把sed的动作限制在第一行('1')到第一行加上'* /'(转义:'\ * \ /')。 – Cyrus

-1
sed '/\/\*/,/\*\// s/.*//g' filename | awk '!/^$/' 
  1. 匹配的模式范围和无替换所有。
  2. 删除空行

输出:

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

这会删除所有不是OP所需的注释。 – Idr

+0

是的,我完全正确地阅读了这个问题 – Sadhun