11

如果所有评论以 /* 开头并以 */ 结尾,我该如何删除它们?我尝试了以下方法。它适用于一行注释。

sed '/\/\*/d' 

但它不会删除多行注释。例如,第二行和第三行不会被删除。

/*!50500 PARTITION BY RANGE (TO_SECONDS(date_time ))
 PARTITION 20120102parti VALUES LESS THAN (63492681600),
(PARTITION 20120101parti VALUES LESS THAN (63492595200) */ ;

在上面的例子中,我需要保留最后一个;在结束评论标志之后。

4

7 回答 7

18

这是使用GNU sed. 像这样跑sed -rf script.sed file.txt

内容script.sed

:a
s%(.*)/\*.*\*/%\1%
ta
/\/\*/ !b
N
ba

或者,这是一个班轮:

sed -r ':a; s%(.*)/\*.*\*/%\1%; ta; /\/\*/ !b; N; ba' file.txt
于 2012-10-25T05:22:17.553 回答
13

如果这是在 C 文件中,那么您必须为此使用 C 预处理器并结合其他工具来临时禁用特定的预处理器功能,例如扩展 #defines 或 #includes,所有其他方法在极端情况下都会失败。这适用于所有情况:

[ $# -eq 2 ] && arg="$1" || arg=""
eval file="\$$#"
sed 's/a/aA/g; s/__/aB/g; s/#/aC/g' "$file" |
          gcc -P -E $arg - |
          sed 's/aC/#/g; s/aB/__/g; s/aA/a/g'

将其放入 shell 脚本并使用您要解析的文件的名称调用它,可选地以“-ansi”之类的标志作为前缀,以指定要应用的 C 标准。

有关详细信息,请参阅https://stackoverflow.com/a/35708616/1745001

于 2012-10-25T06:17:46.330 回答
8

这应该做

 sed 's|/\*|\n&|g;s|*/|&\n|g' a.txt | sed '/\/\*/,/*\//d'

对于测试:

一个.txt

/* Line test
multi
comment */
Hello there
this would stay 
/* this would be deleteed */

命令:

$ sed 's|/\*|\n&|g;s|*/|&\n|g' a.txt | sed '/\/\*/,/*\//d'
Hello there
this would stay 
于 2012-10-25T05:00:09.243 回答
3

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

sed -r ':a;$!{N;ba};s|/\*[^*]*\*+([^/*][^*]*\*+)*/||' file

无论如何,这是一个开始!

于 2012-10-25T07:07:13.317 回答
2

To complement Ed's answer (focused on C files), I would suggest the excellent sed script remccoms3.sed by Brian Hiles for non-C files (e.g. PL/SQL file). It handles C and C++ (//) comments and correctly skips comments inside strings. The script is available here: http://sed.sourceforge.net/grabbag/scripts/remccoms3.sed

于 2013-09-26T14:42:31.613 回答
0

尝试这个

sed "/^\//,/\/;/d" filename
于 2014-05-30T15:55:43.573 回答
0

sed仅解决方案:

sed -r 's/\/\*(.*?)\*\///g' \
    | sed -r 's/(.+)(\/\*)/\1\n\2/g'\
    | sed -r 's/(\*\/)(.+)/\1\n\2/g' \
    | sed '/\/\*/,/\*\// s/.*//'

缺点:多行注释会留下空行(因为 sed 是基于行的,除非你付出了超人的努力)。

解释

  • s/\/\*(.*?)\*\///g将处理单行注释。
  • s/(.+)(\/\*)/\1\n\2/g并将s/(\*\/)(.+)/\1\n\2/g在多行注释的开头和结尾拆分行。
  • /\/\*/,/\*\// s/.*//将运行命令s/.*//有效地删除模式之间的所有行\/\*\*\/- 这是/**/转义。
于 2018-12-19T12:23:05.880 回答