【问题标题】:I need to replace C comments with a blank space or new line using sed我需要使用 sed 用空格或新行替换 C 注释
【发布时间】:2021-07-12 06:06:23
【问题描述】:

输入文件是这样的

#include <stdio.h>

int main()
{
    // this is a function
    float alpha = 0;
    // test
    /* */
    int y = 11; // comment
    y = y + 15;
    //
    char z = 'n';
    /* end of file 
    c */
}

所需的输出应该是这样的

#include <stdio.h>

int main()
{
    *
    float alpha = 0;*
    *
    *
    int y = 11; *
    y = y + 15;*
    *
    char z = 'n';*
*
*
}

这里*代表EOL。

我已经尝试过了,但它也只是删除了空格和新行。

sed '/^[ \t]*\/\//d;/\/*\*\//d;/^[ \t]*\/\*/d' $[input file]

【问题讨论】:

  • 恕我直言,专家始终建议使用了解代码格式样式的工具来编辑代码,可能是一些可以理解 C 格式的工具 sed 可能会这样做,但您可能会遇到问题如果您的实际文件与显示的示例不同。
  • 我需要做一个正则表达式,以便它可以删除任何C文件中的cmets
  • 确保const char *s = "foo // bar"; 不会破坏它。
  • 这不是 K&R 的练习吗?除非没有正则表达式;大多数解决方案最终都会创建一个状态机 iirc。
  • 任何使用sed 的通用解决方案或类似的基于正则表达式的解决方案都将与正则表达式看到注释而编译器没有的各种情况发生冲突。例如,printf("/* this is not a comment */");。变体包括 '/*''*/''//' — 允许使用多字符字符常量,尽管值是实现定义的。那是在你开始处理反斜杠换行符之前。尽管很少有人这样做,但您可以使用反斜杠换行符跨行拆分注释开始或结束标记。此外,// cmets 由反斜杠换行符继续。

标签: regex linux sed


【解决方案1】:

这可能对你有用(GNU sed):

sed -z 's#//[^\n]*##g
        s#/\*#\x00#g
        s#\*/#\x01#g
        s/\x00[^\n\x00\x01]*\x01//g;tb
        :b;s/\x00[^\x01\n]*\n/\n\x00/;tb;s/\x00[^\n]*\x01//;tb' file

解决方案分为三个部分:

  1. 单行 cmets 已删除
  2. 单行上的多行 cmets 已删除。
  3. 多行上的多行 cmets 被删除,但这些行的换行符被保留。

解决方案使用-z 选项,如果文件包含null 字符,可能会导致问题。

注意该解决方案只是部分解决方案,因为许多极端情况可能会破坏它,例如文字 cmets 作为变量值的一部分。

【讨论】:

  • 请参阅我的notes,了解您的脚本是如何被愚弄的。
  • @JonathanLeffler 请注意我所有解决方案的第二个字!
【解决方案2】:
sed 's/\/\/.*//;s/\/\*.*//;s/.*\*\///' file

该命令的工作方式如下:- 第一部分搜索字符串“//”,然后在同一行中删除其后跟的 {string}。第二部分搜索字符串“/”,然后在同一行中删除它后面的 {string}。第三部分搜索字符串“/”,然后在同一行中删除它后面的 {string}。给定解决方案的失败是多行注释超过 2 行

【讨论】:

  • 请在您的答案中添加一些解释,以便其他人可以从中学习
  • 该命令的工作方式如下:- 第一部分搜索字符串“//”,然后在同一行中删除它后面的 {string}。第二部分搜索字符串“/*”,然后在同一行中删除它后面的 {string}。第三部分搜索字符串“*/”,然后在同一行中删除它后面的 {string}。给定解决方案的失败是多行注释超过 2 行。
  • 请通过编辑将所有解释添加到您的答案中
  • http://example.com这样的字符串呢?您的正则表达式将保留 http: 并删除其余部分。不确定这是想要的行为!
猜你喜欢
  • 2012-07-28
  • 2013-12-28
  • 1970-01-01
  • 2014-01-26
  • 1970-01-01
  • 2018-09-06
  • 2011-10-27
  • 2016-11-03
  • 2020-06-09
相关资源
最近更新 更多