我正在尝试将单行“C”样式注释转换为“C++”样式。下面的“sed”还不错,但是如果任何前导代码(注释之前的代码)中有任何“/”,它当然会失败:
sed -i 's,\(^[^\/]*\)\/\*\([^\*]*\)\*\/[ ]*$,\1\/\/\2,' filename
我希望我能做的是这样的:
... [^\\/\\*] ...
即否定“/*”,这当然不起作用,但是经过几个小时的搜索,我找不到简单的解释如何正确地做到这一点:(这似乎不应该是火箭科学。
例如,这些字符串:
blah blah /* comment */
blah blah / blah /* comment */
blah blah /* comment */ blah
blah blah / blah /* comment */ blah
...应该这样转换:
blah blah // comment
blah blah / blah // comment
blah blah /* comment */ blah (this CAN'T be converted)
blah blah / blah /* comment */ blah (this CAN'T be converted)
...显然,如果“C”注释后面有代码,则不会发生转换。
我将在文件之前和之后进行仔细的视觉比较,因此不需要在文字中处理“/*”,也不想转换任何多行内容。
请注意,我认为这是一个“否定”问题,但也许还有另一种方法。我只需要捕获“/*”之前的所有内容,我不在乎如何捕获。
跟进下面的答案
好吧该死!我发现我完全误解了一些基本的东西:
.*/\*
...读取:“除了斜杠星号后跟斜杠星号之外的任何内容”,所以实际上我免费得到了我的“否定”:-)
所以,比 Barmar 更进一步:
sed -i 's,^\(.*\)/\*\(.*\)\*/\s*$,\1//\2,' filename
...甚至会捕捉到这个:
blah / * blah /* co / mme * nt */
并输出:
blah / * blah // co / mme * nt
启示。
答案1
尝试这个:
sed 's,^\(.*\)/\*\([^/]*\)\*/$,\1//\2,'
这不会转换包含嵌入/
字符的注释。或者,您可以使用:
sed 's,^\(.*\)/\*\(.*\)\*/$,\1//\2,'
如果同一行有两个注释,这会做错误的事情,例如
blah blah /* comment1 */ blah /* comment2 */
将转换为
blah blah // comment1 */ blah /* comment2
使用 PCRE 版本可能会做得更好sed
,因为您可以使用负前瞻来测试嵌入的注释。
另请注意,,
在命令中用作分隔符s
意味着您不必转义/
正则表达式中的所有字符——这就是/
当正则表达式包含大量/
.
答案2
也许最安全的方法是首先测试您不想影响的行,b
如果有匹配则退出脚本。
sed '\|\*/.*/\*|b'
*
里面有所有的星星,这有点难以阅读,但基本上 if/*
发生后将*/
sed
退出执行其脚本,自动打印该行,并拉入下一行以开始下一行循环。对于匹配的行,不会执行其后的任何命令。
另一种方法是使用t
est,如果在成功替换后b
未提供任何牧场标签,则同样会从脚本中牧场牧场:b
s///
sed 's|/\*|&|2;t'
它尝试用自身替换该行中第二次出现的模式,如果成功,它会以相同的方式进行分支b
。
所以...
sed 's|/\*|&|2;s|\*/|&|2;t
s|/\*\(.*\)\*/ *$|//\1|'
...将以第一次且唯一一次出现的以及任意数量的尾随空格字符/*
结尾//
的行替换第一次且唯一一次出现的 。*/
这是有效的,因为t
适用于在其之前发生的任何替换,因此如果其中一个或另一个t
成功,sed
则会分支。
不过,我可能在这里犯了错误,因为我对 C 或 C++ 不太熟悉,并且不确定在这种/\*.*\*/.*\*/
情况下会发生什么 - 上面的脚本b
远离了 .也许您应该只测试 2*/
或仅测试 2 /*
。但至少希望我能够将这一概念传达给更了解的人。
答案3
我碰巧需要上述内容 - 但也需要多行 - 所以我将 Barmar 的答案与我自己的一些 sed 合并来实现此目的
sed -e '/\/\*/,/\*\//{s/^\( *\)\/\*/\1~~/g;s/^\( *\) \*\//\1~~/g;s/^\( *\) \*/\1~~/g;s/~~/\/\//g};s/\*\*/\/\//g;s,^\(.*\)/\*\(.*\)\*/\s*$,\1//\2,'
(顺便说一句,如果在 Mac 上,您需要 gsed,否则您会收到上面的错误)
这是之前/之后的差异
***************
*** 1,13 ****
! /*
FOO
! */
! /*
! * BAR
! */
! blah blah /* comment */
! blah blah / blah /* comment */
blah blah /* comment */ blah
blah blah / blah /* comment */ blah
--- 1,13 ----
! //
FOO
! //
! //
! // BAR
! //
! blah blah // comment
! blah blah / blah // comment
blah blah /* comment */ blah
blah blah / blah /* comment */ blah