【问题标题】:Deleting multiple types of comments with sed command [duplicate]使用 sed 命令删除多种类型的注释 [重复]
【发布时间】:2020-04-25 15:05:58
【问题描述】:

我有一个 C 文件目录。我想从这些源文件中删除所有类型的 cmets。

例如,假设我有一个类似于以下文件的源代码。

#include <stdio.h>
int main() {   
 int number;
 /* Sample Multiline Comment 
 * Line 1
 * Line 2
 */
 printf("Enter an integer: ");  

 // reads and stores input
 scanf("%d", &number);
 printf("You entered: %d", number); //display output 

 return 0;
 /* Comment */
}

我想删除这段代码中所有类型的 cmets。这包括,

//    
/* */   
/*
*
*/

我已尝试使用 sed 命令执行此任务。

find . -type f |xargs sed -i 's,/\*\*,,g;s,\*/,,g;s,/\*,,g;s,//,,g'

这只会删除上面的注释符号本身,而不是注释。我想删除整个评论以及上述三个评论符号。

我怎样才能达到这个标准。

【问题讨论】:

  • 恕我直言,我认为任何其他工具都不适用于此任务,这也可能导致误报。那么为什么不使用该语言本身的东西更好呢?
  • @coder:有没有想到strcpy(s, "// this is not a comment")这样的语句?
  • 这能回答你的问题吗? Remove comments from C/C++ code

标签: regex linux shell sed comments


【解决方案1】:

从两个角度来解决这个问题。

  1. 您删除了以匹配条件开头的行
  2. 您删除了以某些标准开头并以不同标准结尾的内容。

删除以条件开头的行:

sed '/^\/\// d'

在开始和结束使用之间删除:

sed 's/\/\*.*\*\/://'

警告。当您有其他可能以适用字符开头的行时要小心。

我希望这就是你要找的。​​p>

【讨论】:

  • 对不起,这对我不起作用。我用你的代码运行了以下命令,find . -type f |xargs sed -i '/^\/\// d' 但是显示没有效果。
  • @agent82 :在做这个面向行的时候要小心。一个 C 程序可能有一个跨越多个物理行的逻辑行,通过以反斜杠结束一行。
  • 如何查找.. -type f -print0 | xargs -0 sed -i '/^\/\// d' 。还可以先尝试在一个文件的 cat 上使用 sed 命令,以确保它在将其菊花链到查找之前执行您想要的操作。
  • @agent82 不,它仍然不起作用
【解决方案2】:

这是对awk 的一种超时尝试,但也许会有所帮助:

#! /usr/bin/env bash    

awk '
    function remove_comments(line)
    {
        # multi-line comment is active, clear everything
        if (flag_c == 1) {

            if (sub(/.*[*][\/]$/, "", line)) {
                flag_c=0
            }
            else {
                # skip this line
                # its all comment
                return 1
            }

        }

        # remove multi-line comments(/**/) made on the same line
        gsub(/[\/][*].*[*][\/]/, "", line)

        # remove single line comments if any
        sub(/[\/][\/].*$/, "", line)

        # make flag_c=1 if a multi-line comment has been started
        if (sub(/[\/][*].*/, "", line))
        {
            flag_c=1
        }

        return line
    }

    ##
    #   MAIN
    ##
    {
        $0 = remove_comments($0)

        if ($0 == 1 || $0 == "")
            next

        print
    }
' file.c

【讨论】:

  • 很抱歉被挑剔了,但是对于printf("http://www.foo.bar"); 之类的语句来说它失败了,恐怕如果没有该语言的解析器,我们就无法可靠地删除 cmets。
  • @tshiono,是的,这是有道理的。该脚本会将字符串中的// 视为注释。同意,了解该语言的解析器非常可靠!
【解决方案3】:

您最好为此使用 C 预处理器,如Remove comments from C/C++ code 的答案。

您可以通过运行gcc -fpreprocessed -dD -E foo.c 要求预处理器删除 cmets。

$ cat foo.c
#include <stdio.h>
int main() {
 int number;
 /* Sample Multiline Comment
 * Line 1
 * Line 2
 */
 printf("Enter an integer: ");

 // reads and stores input
 scanf("%d", &number);
 printf("You entered: %d", number); //display output

 return 0;
 /* Comment */
}
$ gcc -fpreprocessed -dD -E foo.c
# 1 "foo.c"
#include <stdio.h>
int main() {
 int number;




 printf("Enter an integer: ");


 scanf("%d", &number);
 printf("You entered: %d", number);

 return 0;

}

【讨论】:

    猜你喜欢
    • 2021-12-11
    • 1970-01-01
    • 2014-11-16
    • 1970-01-01
    • 2014-06-08
    • 2023-03-18
    • 2017-10-02
    • 2012-11-12
    • 1970-01-01
    相关资源
    最近更新 更多