【问题标题】:How to make sed remove lines not matched by a substitution如何使 sed 删除与替换不匹配的行
【发布时间】:2012-01-03 18:41:40
【问题描述】:

我基本上想这样做:

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

不必写两次表达式:

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

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

【问题讨论】:

  • 使用 -n 选项(如 sed -n)来抑制输出并使用 p 选项(在你的 g 旁边,如 /g;p 仅打印发生更改的那些行。跨度>
  • 您好 Ropez,我已将回复放在答案部分以便更好地格式化。

标签: regex sed substitution


【解决方案1】:

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

$ 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

【讨论】:

  • 新的赢家!选择它是因为它比其他选择更容易记住。
【解决方案2】:

这可能对你有用:

sed '/<expression>/!d;s//<replacement>/g' file

或者

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

【讨论】:

  • "cat file" 只是一个例子,在实际用例中,输入来自一个 git 命令。
【解决方案3】:
cat file | sed -n '/<expression>/{s//<replacement>/g;p;}'

【讨论】:

  • +1,但请注意 "...g;p;}" 是非标准的,不适用于所有 sed。还有,UUOC。
  • @WilliamPursell 请详细说明其中的哪一部分是非标准的? ...g;p} 仅适用于 gnu sed,但据我所知,我输入答案的方式是标准的。
  • 某些版本的 sed 不允许使用 ';'分隔命令,但需要实际的回车。那些版本的 sed 使用起来很烦人;)
  • @WilliamPursell 好吧,根据spec,用; 分隔命令是标准的:Command verbs other than {, a, b, c, i, r, t, w, :, and # can be followed by a semicolon, optional &lt;blank&gt;s, and another command verb. However, when the s command verb is used with the w flag, following it with another command in this manner produces undefined results.,所以那些“其他”sed 实现被破坏了:)
【解决方案4】:

怎么样:

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

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

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

【讨论】:

    最近更新 更多