2016-08-18 40 views
3

如果我做可以grep只打印匹配的缓冲区?

# perl -lne "print \$1 if /'?(\d{5})'?:/" courses.yaml 
00000 
01005 

然后我得到我想要的结果,但现在我想用grep,而不是去做。

为什么不给我同样的输出?

# grep -oP "\'?(\d{5})\'?:" courses.yaml 
'00000': 
'01005': 
+1

因为它返回与正则表达式匹配的所有东西。你可能想要使用'\ K'或者一些先行/后退。 – fedorqui

+1

您在第一种情况下打印组1的内容,并在第二种情况下打印整个比赛。尝试'grep -oP“(\ d {5})(?='?:)”courses.yaml' –

+1

[This answer](http://unix.stackexchange.com/a/13472)提供了关于使用lookahead/lookbehind断言使'-o'按照你想要的方式工作。 – user4815162342

回答

3

您在第一种情况下打印组1内容,在第二种情况下打印组1内容。当使用grep-oP,你只能打印整场比赛,因此,使用(?='?:)前瞻只会返回一个5位数的块,如果有一个:后,他们前面有一个可选的单引号:

echo "'00000': '01005':" | grep -Po "\d{5}(?='?:)" 

请参阅demo

我认为在这里使用lookbehind没有意义,因为'在您的模式中是可选的。

0

-o是输出匹配($&),而不是第一次捕获($1)。

您可以使用\K,后视和/或前瞻来控制所考虑的匹配项。

在你的情况,你可以使用以下命令:

grep -oP "'?\K\d{5}(?='?:)" courses.yaml 

但是简化为以下几点:

grep -oP "\d{5}(?='?:)" courses.yaml 

使用正确的YAML解析器将使更为明智,它仍然坚持很短。