我需要在C ++源代码中进行一些查找和替换:将所有_uvw
替换为xyz
,除非_uvw
属于abc_uvw
或{{1} }}。例如:
def_uvw
应该成为:
abc_uvw ghi_uvw;
jkl_uvw def_uvw;
到目前为止,我想出了以下内容:
abc_uvw ghixyz;
jklxyz def_uvw;
这将仅在不包含find . -type f -print0 | xargs -0 sed -i '/abc_uvw/\!s/_uvw/xyz/g'
的行中替换所有_uvw
xyz
,其中(1)不会处理此类情况:{ {1}}和(2)没有考虑第二个例外,即abc_uvw
。
那么如何用sed做那种选择性的查找和替换呢?
答案 0 :(得分:2)
这可能适合你(GNU sed):
sed -r 's/(abc|def)_uvw/\1\n_uvw/g;s/([^\n])_uvw/\1xyz/g;s/\n//g' file
在您不想更改的字符串前面插入换行符。更改那些没有换行符的字符串。删除任何换行符。
N.B。选择换行符,因为它不能存在于纯粹的sed缓冲区中。
答案 1 :(得分:1)
这个怎么样?
$ cat file
abc_uvw ghi_uvw;
jkl_uvw def_uvw;
$ sed 's/abc_uvw/foo/g;s/def_uvw/bar/g;s/_uvw/xyz/g;s/foo/abc_uvw/g;s/bar/def_uvw/g' file
abc_uvw ghixyz;
jklxyz def_uvw;
答案 2 :(得分:1)
这将有效:
sed -e 's/abc_uvw/AAA_AAA/g; # shadow abc_uvw
s/def_uvw/DDD_DDD/g; # shadow def_uvw
s/_uvw/xyz/g; # substitute
s/AAA_AAA/abc_uvw/g; # recover abc_uvw
s/DDD_DDD/def_uvw/g # recover def_uvw
' input.cpp > output.cpp
cat output.cpp
答案 3 :(得分:1)
你应该使用负面的lookbehind。例如,在Perl中:
perl -pe 's/(?<!(abc|def))_uvw/xyz/g' file.c
这会对_uvw
或abc
之前没有紧急的def
个实例进行全局替换。
输出:
abc_uvw ghixyz;
jklxyz def_uvw;
Sed是一个很有用的工具,当然它有它的位置,但Perl在正则表达式方面更强大。使用Perl,您可以准确指定您的意思,而不是以更迂回的方式解决问题。
答案 4 :(得分:0)
sed 's/µ/µm/g;s/abc_uvw/µa/g;s/def_uvw/µd/g
s/_uvw/xyz/g
s/µd/def_uvw/g;s/µa/abc_uvw/g;s/µm/µ/g' YourFile
这就像概念中的另一个,但是&#34;逃避&#34;首先是在abc和def上过滤的临时模式。我使用µ
但其他字符是可能的,只需避免像/
,\
,&
这样的特殊sed字符,...