[英]Selective find/replace with sed
我需要在C ++源代码中进行一些查找和替换:用xyz
替换所有出现的_uvw
,除非_uvw
是abc_uvw
或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'
这将仅在不包含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
的所有实例(而不是紧随其后的abc
或def
进行全局替换。
输出:
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.