在 sed 中捕获组

Posted

技术标签:

【中文标题】在 sed 中捕获组【英文标题】:capturing groups in sed 【发布时间】:2011-03-19 03:53:41 【问题描述】:

我有很多行表格

ko04062 ko:CXCR3
ko04062 ko:CX3CR1
ko04062 ko:CCL3
ko04062 ko:CCL5
ko04080 ko:GZMA

并且非常希望摆脱右侧列的 ko: 位。我正在尝试使用sed,如下:

echo "ko05414 ko:ITGA4" | sed 's/\(^ko\d5\)\tko:\(.*$\)/\1\2/'

它只是输出我回显的原始字符串。我对命令行脚本、sed、管道等非常陌生,所以如果/当我做一些非常愚蠢的事情时,请不要太生气。

让我感到困惑的主要事情是,如果我将\1\2 位反转为读取\2\1 或仅使用一组,也会发生同样的事情。我想,这意味着我遗漏了一些关于将 echo 的输出通过管道传输到 sed 的机制,或者我的正则表达式错误,或者我使用 sed 错误,或者 sed 没有打印替换的结果.

任何帮助将不胜感激!

【问题讨论】:

有什么理由不能使用 sed 's/ko\://g' ? 有什么理由不使用 perl? :-P 不懂 Perl!现在学习sed。将在必要时学习 perl 和其他任何东西...... @Anders .... 因为我不知道 sed 这么棒? ***.com/questions/2777579/… 【参考方案1】:

@OP,如果你只是想摆脱“ko:”,那么

$ cat file
ko04062 ko:CXCR3
ko04062 ko:CX3CR1
ko04062 ko:CCL3
ko04062 ko:CCL5
some text with a legit ko: this ko: will be deleted if you use gsub.
ko04080 ko:GZMA

$ awk 'sub("ko:","",$2)1' file
ko04062 CXCR3
ko04062 CX3CR1
ko04062 CCL3
ko04062 CCL5
some text with a legit ko: this ko: will be deleted if you use gsub.
ko04080 GZMA

请注意。虽然您可以使用纯 bash 字符串替换,但只有在更改单个字符串时才会更有效。如果你有一个文件,尤其是一个大文件,使用 bash 的 while 读取循环仍然比使用 sed 或 awk 慢。

【讨论】:

【参考方案2】:

应该这样做。您也可以跳过最后一组并简单地使用 \1 代替,但由于您正在学习 sed 和正则表达式,这是个好东西。我想在中间使用一个非捕获组(:? ),但无论出于何种原因,我都无法让它与 sed 一起玩,也许它不受支持。

sed --posix 's/\(^ko[0-9]\5\\)\( ko:\)\(.*$\)/\1 \3/g' file > result

当然你也可以使用

sed --posix 's/ko://'

【讨论】:

非常感谢!我赞成您的回答,因为您已经完全做到了这一点,并且 's/ko://' 很棒(尽管那个反引号在做什么?)。我给 ninjalj 打勾,因为他的回答 + cmets 已经解释了我做错了什么。但我肯定会坚持使用 's/ko://' 或者甚至将字符串替换为 getekha!我看看哪个更快... 我的错,变量的剩余部分。是的,我也会给他,他实际上很费心解释。【参考方案3】:

您不需要为此使用 sed

以下是使用 bash 的方法:

var="ko05414 ko:ITGA4"
echo $var//"ko:"

$var//"ko:" 将所有的 "ko:" 替换为 ""

更多信息请见Manipulating Strings

【讨论】:

当我 /am/ 学习 sed 时,这种方法让我觉得既聪明又简单。我不知道这种语法。所有这些命令行 fu 都很棒。 我的错误,我向 getekha 道歉。【参考方案4】:

sed 正在输出其输入,因为替换不匹配。由于您可能正在使用 GNU sed,请尝试以下操作:

echo "ko05414     ko:ITGA4" | sed 's/\(^ko[0-9]\5\\)\tko:\(.*$\)/\1\2/'
\d -> [0-9] 因为 GNU sed 无法识别 \d -> \\ 因为 GNU sed 默认使用基本的正则表达式。

【讨论】:

这仍然给我同样的错误。我在 OSX - 不知道如何确定我是否在使用 GNU sed... @Mike Dewar -- 哦,这是重要的信息......我认为 OS X 使用了类似 BSD 的 sed,而这里的一个常见假设是人们使用 GNU sed 知道这一点很重要!非常感谢! 在 OSX 上,GNU sed 被称为 gsed

以上是关于在 sed 中捕获组的主要内容,如果未能解决你的问题,请参考以下文章

使用 sed 在捕获组内替换

具有捕获组的有效正则表达式,但 sed 脚本不起作用

在 Shell 脚本中捕获命名组

捕获包含模式正则表达式的每个单词

多行上的 sed 正则表达式无法捕获所有

捕获组之前或捕获组之后的正则表达式,具有单个捕获组