假设我有一个以以下内容开头的文件
/*********************************************************
blah blah blah
blah blah blah
blah blah blah
*********************************************************/
Actual code follows here
code
code
code
我使用的命令:
sed -i 's/(/*).*(*/)/\1 newcomment \2/1' file
但我收到了错误消息
sed: -e expression #1, char 14: unknown option to `s'
PS我的问题是...我怎样才能用其他bloah bloah bloah评论替换“blah blah blah...”评论?
答案1
使用以下方法更容易完成perl
:
perl -0777 -pi -e 's{/\*.*?\*/}{/* new comment */}s' file.c
/*...*/
将用新注释替换第一次出现的。
sed
一次处理一行文本,因此您无法匹配多行文本,除非您将其他行添加到模式空间(或者-z
与最新版本的 GUN 一起使用sed
):
sed -zi 's|/\*.*\*/|/* new comment */|' file.c
或者可移植(假设短文件):
sed -e :1 -e '$!{N;b1' -e '}' -e 's|/\*.*\*/|/* new comment */|' file.c
但请注意,由于sed
不支持 的*?
非贪婪运算符perl
,这意味着它将从第一次出现/*
到最后的发生*/
,因此将替换/* comment 1 */ some C code /* comment 2 */
为/* new comment */
。
这样做sed
是可能的,但会更痛苦。看这里举个例子(这也避免了/*
内部发生"strings"
以及其他一些警告)。
与该解决方案等效的简化解决方案perl
如下:
sed '
# load the whole file into the pattern space
:1
$!{
N;b1
}
s/_/_u/g;s/>/_c/g; # use _ as an escape character to escape
# the > we will be using in place of */
s|\*/|>|g; # replace */ with >
s|/\*[^>]*>|/* new comment */|
s|>|*/|g; # undo the replacement and escaping
s/>/_c/g;s/_u/_/g' file.c
使用 GNU awk
,你可以这样做:
awk -v RS='\\*/' '
!found && sub(/\/\*.*/, "/* new comment ") {found = 1}
{printf "%s", $0 RT}' file.c
答案2
转义括号和斜线
sed -i 's/\(\/*\).*\(*\/\)/\1 newcomment \2/1' file