繁体   English   中英

选择性查找/替换为sed

[英]Selective find/replace with sed

我需要在C ++源代码中进行一些查找和替换:用xyz替换所有出现的_uvw ,除非_uvwabc_uvwdef_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'

这将仅在不包含abc_uvw的行中用xyz替换所有_uvw ,其中(1)不能处理这种情况: abc_uvw ghi_uvw; 并且(2)不考虑第二个例外,即def_uvw

那么,如何有选择地查找并替换为sed呢?

这可能对您有用(GNU sed):

sed -r 's/(abc|def)_uvw/\1\n_uvw/g;s/([^\n])_uvw/\1xyz/g;s/\n//g' file

在您不想更改的字符串的前面插入换行符。 更改前面没有换行符的那些字符串。 删除任何换行符。

NB选择Newline,因为它不能存在于纯净的sed缓冲区中。

这个怎么样?

$ 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;

这将起作用:

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

您应该使用负向后看。 例如,在Perl中:

perl -pe 's/(?<!(abc|def))_uvw/xyz/g' file.c

_uvw的所有实例(而不是紧随其后的abcdef进行全局替换。

输出:

abc_uvw ghixyz;
jklxyz def_uvw;

Sed是有用的工具,当然也有它的位置,但是Perl在正则表达式方面要强大得多。 使用Perl,您可以准确地指定您的意思,而不是以更round回的方式解决问题。

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

这与其他概念类似,但是首先“转义”要对abc和def进行过滤的临时模式。 我使用µ但其他char也可以,只是避免使用特殊的sed char,例如/\\& ,...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM