如何使用sed删除未被替换匹配的行

28

我基本上想做这件事:

cat file | grep '<expression>' | sed 's/<expression>/<replacement>/g'

无需写两次表达式:

cat file | sed 's/<expression>/<replacement>/g'

有没有办法告诉sed不要打印与替换命令中的正则表达式不匹配的行?


2
使用-n选项(如sed -n)来抑制输出,并使用p选项(紧挨着g,如/g;p)仅打印发生更改的行。 - jaypal singh
嗨,Ropez,我已将响应放置在答案部分以获得更好的格式。 - jaypal singh
4个回答

34

假设你有一个包含需要替换文本的文件。

$ cat new.text 
A
B
如果你想将 A 改为 a,理想情况下应该执行以下步骤 -
$ sed 's/A/a/' new.text 
a
B

但是如果您不希望获取未受替换影响的行,则可以使用以下n和p的组合方式 -

$ sed -n 's/A/a/p' new.text 
a

新获胜者!被选中是因为它比其他选择更容易记住。 - Ropez

18
这可能适用于你的情况:
sed '/<expression>/!d;s//<replacement>/g' file

或者

sed 's/<expression>/<replacement>/gp;d' file

“cat file”只是一个例子,在实际使用中,输入来自于git命令。 - Ropez

4
cat file | sed -n '/<expression>/{s//<replacement>/g;p;}'

1
+1,但请注意,“...g;p;}"是非标准的,不会在所有sed中起作用。另外,UUOC。 - William Pursell
@WilliamPursell,您能详细说明哪一部分是非标准的吗?...g;p}仅适用于gnu sed,但我在答案中提供的方式是标准的,据我所知。 - mitchnull
一些版本的sed不允许使用“;”来分隔命令,而是需要实际的回车符。那些版本的sed使用起来非常烦人 ;) - William Pursell
@WilliamPursell 嗯,根据规范,使用分号;来分隔命令是标准的:除了 {, a, b, c, i, r, t, w, :, 和 # 之外的命令动词可以后跟一个分号、可选的空格和另一个命令动词。但是,当 s 命令动词与 w 标志一起使用时,在此方式后面再跟另一个命令会产生未定义的结果。因此,那些“其他”sed实现是有问题的 :) - mitchnull

-3

这样怎么样:

cat file | sed 'd/<expression>/'

将匹配的模式从输入中删除。当然,这与您想要的相反,但也许您可以制作一个相反的正则表达式?

请注意,我不完全确定语法,只是在一段时间前使用过几次。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接