我想在多个文件(cpp代码)中搜索某个字符串A,并用字符串C替换下一次出现的字符串B。
**示例:
traceDebug( "text" ) );
结果应为:
traceDebug( "text" );
String A = "traceDebug"
String B = ") );"
String C = ");"
因此,第一个occurence of ") );
应该替换为);
。
我不能简单地删除)
,因为如果我愿意的话,文件中会存在语法错误的星座。
答案 0 :(得分:0)
像这样吗?
$ cat foo.txt
traceDebug ( "text" ) );
ignoreMe ( "text" ) );
traceDebug
( "text" ) );
) );
$ sed '/traceDebug/s/) );/);/;t;/traceDebug/,/) );/s/) );/);/' foo.txt
traceDebug ( "text" );
ignoreMe ( "text" ) );
traceDebug
( "text" );
) );
t
是一个条件分支,如果单行替换更改了该行,它将忽略范围替换。就个人而言,如果需要使用分支,我会开始考虑使用sed
以外的工具!
答案 1 :(得分:0)
您可以使用Perl一线式实现:
perl -i.bak -pE 'BEGIN { undef $/; } s/traceDebug.+?\K\) \);/\);/gs' whatever_files*.cpp
编辑要在bash
的子目录中的文件上运行此操作,最简单的方法可能是:
( shopt -s globstar ; perl -i.bak -pE 'BEGIN { undef $/; } s/traceDebug.+?\K\) \);/\);/gs' **/*.cpp )
示例输入:
traceDebug ( "text" ) );
traceDebug
( "text" ) );
) );
do_not_replace (3 * ( 4 + 5 ) );
示例输出:
traceDebug ( "text" );
traceDebug
( "text" );
) );
do_not_replace (3 * ( 4 + 5 ) );
说明:
-i.bak
:就地编辑;原始文件另存为foo.cpp.bak
BEGIN { undef $/; }
:不要换行,而是立即读取整个文件s/traceDebug.+?\K\) \);/\);/gs
:进行替换。
traceDebug.+?
:在.+?
之后尽可能少地{traceDebug
)\K
:将这一部分排除在即将到来的替换项之外\) \);
:我们要更改的内容(在\K
之后)\);
:替代人/gs
:替换所有匹配项( G 小数点),并允许.
匹配换行符,就好像整个字符串是 S 英格线在s///gs
运行之后,Perl自己负责将输入文件重命名为.bak
,并将输出保存在原始文件名下。
答案 2 :(得分:0)
这可能对您有用(GNU sed):
sed '/traceDebug/{:a;s/) );/);/;t;n;ba}' file
将处理范围缩小到包含traceDebug
的行。此后,将) );
替换为);
并纾困。否则,打印当前行,获取下一行并重复直到成功。