2016-08-18 87 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解析器將使更爲明智,它仍然堅持很短。