我需要从我们的存储库中的所有文件中删除某种特征性的单行 C++ 注释。代码看起来像这样:
some_code
// characteristic_comment_to_delete
some_more_code // another_comment
another_line_with_code // characteristic_comment_to_delete
even_more_code
结果,我想得到这个:
some_code
some_more_code // another_comment
another_line_with_code
even_more_code
我使用 sed 命令使我的结果几乎和我想要的一样好:
$ sed -i -e 's&// characteristic_comment_to_delete.*&&g' some_file.cpp
some_code
some_more_code // another_comment
another_line_with_code
even_more_code
不幸的是,保留这些空行是不可接受的解决方案,因此我需要以某种方式改进我的命令,以便它删除整行,但前提是在删除此特定注释后将其保留为空白。
编辑:我显然没有以 root 身份运行这些命令。相应地更改了提示。另外,我不想删除所有评论,所以我不认为我的主题是重复其他线程。
答案1
Sed 有一个d
用于删除整行的命令 - 它也可以采用任意(非/
)分隔符,但是在第一次使用时需要对其进行转义\
。所以你可以做类似的事情
$ sed -e '\#^// characteristic_comment_to_delete$#d' -e 's#// characteristic_comment_to_delete.*##' file
some_code
some_more_code // another_comment
another_line_with_code
even_more_code
首先删除完全由 组成的行// characteristic_comment_to_delete
,然后替换任何剩余的匹配项。
(我将您的更改&
为#
以避免与 sed&
替换运算符混淆)。
答案2
使用 GNU sed
:
sed 's|\s*// characteristic_comment_to_delete.*||;T;/./!d'
T
是一个 GNU 扩展分支除非之前的s
替换成功。因此,如果没有删除任何注释,我们就会分支,并/./!d
跳过下一个(删除该行,除非它至少包含一个字符)。
标准等效:
sed '\/[[:space:]]*\/\/ characteristic_comment_to_delete.*/{s///;/./!d;}'
或者:
sed 's|[[:space:]]*// characteristic_comment_to_delete.*||
t 1
b
:1
/./!d'
仅当替换成功时,两者才会抑制空行。
答案3
如果您接受 AWK 解决方案:
awk -F "[ ]*//[ ]*characteristic_comment_to_delete.*" '$1 != "" { print $1; }' some_file.cpp
注意:该模式在方括号之间包含一个空格和一个制表符[ ]
。
此解决方案无法正确处理包含注释模式的字符串文字,例如
char text[] = "// characteristic_comment_to_delete bla bla";
答案4
我删除特定注释的琐碎任务变得比我预期的要复杂得多,但我找到了一个可行的解决方案,我将其分成几个单独的命令。主要问题是我有这样的行:
another_line_with_code // characteristic_comment_to_delete#xA;more_code // characteristic_comment_to_delete // characteristic_comment_to_delete
#xA;是换行符,但文件的写入方式对于 sed 来说被视为单行。
我必须使用 Perl,因为我无法回避这样一个事实:尽管理论上有很好的正则表达式,但 sed 太贪婪了。
使我能够删除仅包含注释的行的最终解决方案是(感谢 Steeldriver 将我指向“d”参数,我不知道这一点):
$ find . -type f -print0 | xargs -0 sed -i -e '\#^// characteristic_comment_to_delete\s*$#d'
并删除内嵌注释:
$ find . -type f -print0 | xargs -0 perl -pi -e 's|\s*// characteristic_comment_to_delete\s*
||g'
+
$ find . -type f -print0 | xargs -0 perl -pi -e 's|
// characteristic_comment_to_delete\s*||g'
+
$ find . -type f -print0 | xargs -0 perl -pi -e 's|\s*// characteristic_comment_to_delete\s*||g'
可以很容易地减少到只有两个命令,并且可能只用单个命令捕获所有情况,但上面已经完成了工作。谢谢大家!