我正在处理非常大的代码,需要重命名许多API。这包括所有API的前缀。我的API名称类似于:
MyfoobarFilename_FooFighterDoMeAFavor(MyfoobarFilename_FooFighter *FighterInstance, void *Favor)
MyfoobarFilename_FooFighterGetInLine(MyfoobarFilename_FooFighter *FighterInstance, void *Line)
MyfoobarFilename_FooFighterSetATicketForMe(MyfoobarFilename_FooFighter *FighterInstance, void *Ticket)
MyfoobarFilename_FooFighterHelpMeNowInterrupt(MyfoobarFilename_FooFighter *FighterInstance, void *FighterReference)
MyfoobarFilename_FooFighterAreYouOk(MyfoobarFilename_FooFighter *FighterInstance, unsigned int HowAreYou)
我想通过在API名称上添加下划线来更改所有这些名称。
我希望结果如下所示,
MyfoobarFilename_FooFighter_DoMeAFavor(MyfoobarFilename_FooFighter *FighterInstance, void *Favor)
MyfoobarFilename_FooFighter_GetInLine(MyfoobarFilename_FooFighter *FighterInstance, void *Line)
MyfoobarFilename_FooFighter_SetATicketForMe(MyfoobarFilename_FooFighter *FighterInstance, void *Ticket)
MyfoobarFilename_FooFighter_HelpMeNowInterrupt(MyfoobarFilename_FooFighter *FighterInstance, void *FighterReference)
MyfoobarFilename_FooFighter_AreYouOk(MyfoobarFilename_FooFighter *FighterInstance, unsigned int HowAreYou)
但是,我只想替换API名称中的文本,而不替换代码中的其他位置。我可以使用s/FooFighter/FooFighter_/g
,但这也会做出我不想要的更改。
通过使用脚本并执行grep并替换,我可以通过多种方式实现这一目标。
但是,必须有一种使用单个命令(希望使用sed)执行此操作的更快,更聪明的方法。有人可以启发我怎么做。
谢谢。
答案 0 :(得分:1)
我建议使用以下sed
表达式(使用Basic Regular Expression语法):
s/\(\bMyfoobarFilename_FooFighter\)\([a-zA-Z0-9_]\+\b\)/\1_\2/g
其中
\b
转义序列代表“单词边界”(GNU扩展); \( ... \)
创建一个可以在s/regexp/replacement/
命令的“替换”部分中引用的组; \1
和\2
是对第一和第二组的引用; g
指示 sed 将替换项应用于“ regexp”的所有匹配项,而不仅仅是第一个; \+
匹配一个或多个(GNU扩展名)。正如@WiktorStribiżew和@Ed Morton所说,\+
和\b
是GNU扩展。您可以将\+
替换为\{1,\}
。但是我找不到\b
的适当POSIX兼容替代品。如果GNU sed不可用,则可以按以下方式使用Perl:
perl -i -npe \
's/(\bMyfoobarFilename_FooFighter)(\p{L}+\b)/\1_\2/g' file
其中\p{L}
是Unicode character property代表字母。其余部分与上面的sed表达式相似。
您的代码片段看起来像C / C ++函数原型,因此您可能还想修改函数调用和函数指针,例如:
while (MyfoobarFilename_FooFighterHelpMeNowInterrupt ()
&& MyfoobarFilename_FooFighterSetATicketForMe())
{
/* ... */
}
void (*fptr)(MyfoobarFilename_FooFighter *, void *) =
&MyfoobarFilename_FooFighterGetInLine;
答案 1 :(得分:0)
尝试一下:
sed "s/\(MyfoobarFilename_FooFighter\)\(\S*(\)/\1_\2/g" file.txt
说明:
s/ # substitute
\(MyfoobarFilename_FooFighter\) # searchstring in \1
\(\S*(\) # the rest to the bracket in \2
/\1_\2 # insert '_' between \1 and \2
/g # global