【问题标题】:Replace one capture group with another with GNU sed (macOS) 4.4用 GNU sed (macOS) 4.4 替换一个捕获组
【发布时间】:2017-12-05 12:44:26
【问题描述】:

我查看了其他一些外围问题,但未能找到解决问题的方法,所以如果这与我错过的问题重复,我很抱歉。

基本上,我有以下 GNU sed 命令:

sed -E -imr 's/^(\w)+/(\w)+$/g' file

应该用该行的最后一个单词替换一行的第一个单词。

第一个正则表达式^(\w)+ 效果很好,并且匹配每行的第一个单词。问题是该命令将第一个单词替换为文字字符串(w)+$

我尝试转义反斜杠、括号和运算符,但我没有让正则表达式在命令的输出部分工作。

可以使用正则表达式捕获组来替换不同的正则表达式捕获组吗?什么需要转义,或者需要使用什么替代语法?

注意

我在 macOS 上使用来自 brew installed coreutils 的 GNU sed,因此这个问题的答案可能不适用于其他版本的 sed,例如 macOS 上的本机 BSD。

【问题讨论】:

  • 试试sed -E -imr 's/^(\w+)(.*\W)(\w+)$/\3\2\1/g' file (如果\w\W 工作,也许[[:alnum:]][^[:alnum:]] 会更好)。
  • 在替换字段中你不能使用正则表达式语法,但你应该使用纯文本和一些特殊符号(例如\1返回第一个捕获组)。
  • @CasimiretHippolyte 我认为这是因为他在 macos 上使用 GNU sed。本机 sed 命令没有这样的选项。当然,有一个适用于 BSD sed 的解决方案,但他没有使用那个版本。
  • @ezra 我赞成你的问题,将它从 -2 变为 -1。我认为它被否决的原因之一可能是您在标题中使用的名词。如果我写的标题应该是“使用 GNU sed 将一个捕获组替换为另一个捕获组”,甚至可能包括 sed 的版本。
  • @jeff6times7 感谢您的投票,这是有道理的。我觉得无法在网上找到答案的部分原因是没有词汇来搜索正确的答案。有趣的是,有些人对此表示反对,但我也明白为什么标题中的误用短语会令人讨厌。感谢您的提醒。编辑——我也更改了标题以反映您的建议。

标签: regex sed gnu-sed


【解决方案1】:

替换不包含正则表达式,它包含一个可以引用正则表达式中定义的捕获组的字符串。要将第一个单词替换为最后一个单词,您需要捕获最后一个单词和该行的其余部分:

sed -r 's/^\w+(.*\b)(\w+)$/\2\1/'  
            |    |    |
         Matches |    |
         the 1st |    Matches the last word
         word    |
                Matches everything in the middle
                up to a "word boundary"

请注意,-r\w\b 可能不适用于所有 sed 版本,但它们应该可以在最近的 GNU sed 中使用。

【讨论】:

  • OP 正在使用 GNU sed,但如果给出此命令,本机 BSD sed 将抛出错误。 OP 仅将 GNU 部分作为尾随注释提及这一事实,其他阅读问题和您的答案的 macos 用户可能会尝试(就像我一样)您的解决方案,看到错误,然后(就像我一样)想挠头在你的大方向。我的建议是在您的回答中注明这一点,然后要求 OP 非常清楚地进行区分。
  • ... 和 sed 's/\([^[:space:]]*\)\(.*[[:space:]]\)\([^[:space:]]*\)/\3\2\1/' 与任何 POSIX sed。
猜你喜欢
  • 2018-04-27
  • 2017-05-02
  • 2020-12-04
  • 1970-01-01
  • 1970-01-01
  • 2018-07-23
  • 2022-10-07
  • 2010-12-06
  • 1970-01-01
相关资源
最近更新 更多