【问题标题】:How to limit a sed replacement to everything after a particular symbol?如何将 sed 替换限制为特定符号之后的所有内容?
【发布时间】:2012-05-22 12:38:45
【问题描述】:

我正在使用sed 替换文件中的各种文本,例如:

sed -i "s/a/b/g" ./file.txt

我文件中的每一行都包含],它是一个右方括号和一个空格。在此之前,我不想对任何东西进行替换。以下是一些示例行:

This is some text ] This is some other text.
                    ^

我已经放置了一个胡萝卜来标记可以开始替换的位置。其他右方括号可能会出现在该行的后面,但从未出现过,例如:

This is some more text ] This is yet some other text ] This is some more.
                         ^

这将替换胡萝卜之后的所有匹配项。后面的方括号不重要。

  • 如何限制sed 仅替换在第一个] 出现在一行之后找到的匹配项?

【问题讨论】:

  • 是在第一个]之后还是在第一个] 之后(右括号后跟一个空格)?

标签: bash sed replace


【解决方案1】:

你可以这样做:

sed -i 's/^\([^]]*].*\)a/\1b/' file.txt

请注意,您使用的 -i 标志是非 posix 扩展。

【讨论】:

  • +1:我对\+ 部分有所保留;我认为这应该是一个简单的*,因为没有什么说右方括号不能是该行的第一个字符。 -i 选项是 GNU sed 扩展;这也应该注意(尽管这是问题的一部分)。
  • 不过,这不会替换同一行上的多个匹配项。您可以添加一个条件循环,但这会使事情变得有些复杂。
  • @JonathanLeffler 适当指出。查看我的更改。
【解决方案2】:

到目前为止,其他答案仅在“]”之后出现一次时才替换“a”。由于您使用g 全局规范,我假设“a”可能在右括号后出现多次,并且您想替换所有这些。为此,请使用“分而治之”的方法。

$ echo "foo abc ] bar ] baz" | sed 's/] /&\n/;h;s/.*\n//;s/a/X/g;x;s/\n.*//;G;s/\n//'
foo abc ] bXr ] bXz

这只会考虑第一个右方括号。

【讨论】:

  • 严格来说,如果“a”在"] " 之后出现一次,您将替换它。第一个命令应该是s/]/]\n/
  • 如果你的例子是echo "foo abc ]bar ] baz",你的结果就是foo abc ]bar ] bXz
  • @potong:OP声明第一个右方括号后跟一个空格。
  • 请见谅。我应该更仔细地阅读问题而不是摘要。
猜你喜欢
  • 1970-01-01
  • 2020-12-05
  • 1970-01-01
  • 2021-04-30
  • 2017-02-21
  • 1970-01-01
  • 2010-12-12
  • 2013-11-25
  • 1970-01-01
相关资源
最近更新 更多