【问题标题】:Remove first multiline comment from file从文件中删除第一个多行注释
【发布时间】:2016-01-23 19:53:54
【问题描述】:

我正在尝试使用 unix 工具从源文件的大目录中删除所有初始多行 cmets。

比如我有这个文件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

但这会剥离所有多行 cmets 导致:

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

有没有办法做到这一点,并且只删除从文件的第一行开始的多行注释并保留所有其他 cmets?

【问题讨论】:

  • 您要删除许可证吗?
  • 是的,我计划完成后将它们放回去
  • ^ 是用于匹配最开始出现的模式的锚标记。所以像这样使用/^\/\*/,/\*\//d
  • 这是行首的锚点,而不是文件的开始。这并不能解决问题。
  • 查看我的regex。它匹配多行注释的第一次出现。使用g 进行全局搜索。

标签: regex awk sed


【解决方案1】:

这假定在第一个多行注释之前您的文件中没有任何内容。它只是说在您看到结束第一条评论的*/ 后开始打印(然后无论看到什么都不再停止)。

$ 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 语句执行时才到达此处,从而避免打印最后一行初始注释行)。

【讨论】:

  • 不客气;添加了解释 --- 如果还有什么不清楚的地方告诉我。
  • 更简洁:awk 'f; /*\//{f=1}' testfile.c.
【解决方案2】:

1,/\*\//{ ... } 中使用GNU sed 包装你的部分/\/\*/,/\*\//d

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

输出:

int main(int argc, const char *argv[]) { /* 留着我 */ 返回0; } /* 留着我 */

【讨论】:

  • 也可以。您能解释一下您添加的1, 部分吗?
  • 1,/\*\//{ ... } 将 sed 的操作限制在从第一行 (1) 到第一行 */(转义:\*\/)的范围内。
【解决方案3】:

如果您的 cmets 都以相同的方式结束 尝试类似

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

否则,您将不得不更花哨地查看一行的最后两个字符,直到找到第一条评论的结尾。

这具有完成工作后不测试任何行的特性。

【讨论】:

  • 如果getline 失败、有其他问题并且完全不必要地使用getline,这将进入无限循环。见awk.info/?tip/getline`
【解决方案4】:
sed '/\/\*/,/\*\// s/.*//g' filename | awk '!/^$/'
  1. 按模式范围匹配并将全部替换为空。
  2. 删除空行

输出:

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

【讨论】:

  • 这会删除所有不是 OP 想要的 cmets。
猜你喜欢
  • 2011-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-02
  • 1970-01-01
  • 2019-12-04
  • 2015-05-11
  • 1970-01-01
相关资源
最近更新 更多