使用sed删除直到第一次出现结肠


16

我的sed命令是

 sed '/(.*:)/d' <<< 'abcd:bcde:cdeaf'

它必须返回

bcde:cdeaf

(即)必须删除该行中第一个冒号之前的所有字符以及冒号本身。

但这并没有删除任何内容。

我的困惑主要是由于

1)是否需要在sed regex-es内部转义用于模式匹配的括号?

2)在任何情况下(转义/不转义),它均不起作用。我试过了,

sed -E '/\\(.*:\\)/d' <<< 'abcd:bcde'
sed 

1
你想要的sed 's/[^:]*://'d顺便说一句,您并没有删除输入行,而是使用s///ubstitution命令对其进行了修改。您必须完全替换第一个非冒号位和其后的冒号。
mikeserv

解决了这个问题...谢谢,伙计...这是我学习sed内部正则表达式模式匹配的示例...因此,我正在寻找使用带括号的组/模式匹配的答案...

3
或者,仅使用bash:printf "%s\n" "${line#*:}"...
jasonwryan 2015年

1
@jasonwryan-好点,考虑示例源。这绝对是处理它的更有效方法。但如果while read line$line,则sed应该首选。
mikeserv

Answers:


23
$ echo 'abcd:bcde:cdeaf' | sed 's/^[^:]*://g'
bcde:cdeaf

第一个^表示行的开头。这[^:]只是我不懂写冒号的唯一方法。在*冒号后意味着我前右任意数量的东西(在这种情况下,没有冒号)。最后,:选择冒号。

换句话说,选择该行的开头,任意数量的非冒号内容以及第一个冒号。

//g方法删除每个匹配的实例。


3
您不需要^锚定比赛,除非您还添加了一个g小叶标志。模式只能出现1次,因此global标志不会[^:]*:从一行中删除所有模式,就像您不^锚定它一样。与其使正则表达式带有两个不必要的标志(只会使彼此不平衡)并使之复杂化,您可以不理会它们,这就是在您回滚之前,此答案的编辑版本所演示的。为什么您会坚持要传播我所不知道的不良信息,但这使它成为一个错误的答案。
mikeserv

正如我已经说过的,@ mikeserv感谢您指出这一点。衷心感谢您帮助我提高sed技能。我是新手sed,现在还不习惯从我到目前为止所使用的非常有限的语法中走出来。这sed(嘿嘿),我想,即使它是不是最佳的(即你的)回答我的回答解决了OP的问题。这是Stack Exchange,而不是Wikipedia,所以如果我错了,请纠正我,但是如果您知道更好的答案,则应该发布它,以便人们可以看到各种方法并进行比较。请不要使用编辑功能将我的答案变成您的答案。
user1717828 2015-09-29的

4
这不是我的答案。是您的答案,已编辑。就这样。,这是很好的。不再了。
mikeserv

4

要对列进行操作,有cut

echo 'abcd:bcde:cdeaf' | cut -d: -f2-

一样

echo 'abcd:bcde:cdeaf' | cut -d: -f1 --complement

和其他版本一起使用sed(更快地处理大数据):

echo 'abcd:bcde:cdeaf' | sed 's/^://;t;s/:/\n:/;D'

而且颇具异国情调 bash

echo 'abcd:bcde:cdeaf' | { IFS=: read -r first last ; echo "$last" ; }

要么

echo 'abcd:bcde:cdeaf' | { read -r line ; echo ${line#*:} ; }

要么

echo 'abcd:bcde:cdeaf' | { IFS=: read -a a ; printf '%b:' "${a[@]:1}\c" ; echo ;}

您还可以添加使用sed进行操作的正确方法,即sed 's/[^:]*://'
don_crissti

@don_crissti上面的答案中注明了版本。此外,由于使用正则表达式,因此较慢,因为必须在每行中编译表达式。
Costas

不,这不对。上面的答案很浪费时间,值得大量批评-特别是如果您阅读那里的修订和评论。
don_crissti
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.