用sed选择性查找/替换

时间:2014-06-05 08:01:10

标签: regex shell sed

我需要在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做那种选择性的查找和替换呢?

5 个答案:

答案 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

这会对_uvwabc之前没有紧急的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字符,...