2014-03-26 19 views
0

我試圖用sed從git describe的輸出中解析版本號。輸出是以下形式:需要一個可以處理可選子串的正則表達式

vMAJOR.MINOR[-STRING]-REVISION-HASH 

MAJORMINOR,和REVISION是整數。 STRINGHASH是任意字符串,但我只對HASH感興趣。

例子:

v0.1-alpha-3-g9c8c402應該返回0 1 3 g9c8c402

v0.4-beta-10-g3187e7f-dirty應該返回0 4 10 g3187e7f-dirty

v1.0-0-fe35119e應該返回1 0 0 fe35119e

我本來使用:

sed 's/v\([0-9]*\)\.\([0-9]*\)-.*-\([0-9]*\)-\(.*\)/\1 \2 \3 \4/g'

但是,它只適用於可選子字符串存在時。

回答

1

現在不起作用,因爲它期望版本結束脩訂之間有兩個破折號,即使沒有字符串存在。

編輯:我不是很熟悉sed正則表達式,你將需要一個\?而不是?。我還看到\?僅作爲GNU擴展包含,因此不確定它是否會對您有所幫助。

v\([0-9]*\)\.\([0-9]*\)-.*-\?\([0-9]*\)-\(.*\) 

如果\?不工作,你可以嘗試將其指定爲 '零次或一次' 這樣的:

v\([0-9]*\)\.\([0-9]*\)-.*-\{0,1\}\([0-9]*\)-\(.*\) 
+0

啊,我缺少的部分約逃跑''? 'v \([0-9] * \)\。\([0-9] * \) - \?。* - \([0-9] * \) - \(。* \)'工作。第二個短劃線作爲可選的解決方案會導致版本號有時會丟失。 – Merad

+0

哦,是的,這是有道理的,它將包含在'。*'中。感謝您指出了這一點,並很高興能夠提供幫助。 –

0

嘗試:

sed 's/v\([0-9]*\)\.\([0-9]*\)-\([^-]*-\)*\([0-9]*\)-\(.*\)/\1 \2 \4 \5/g' 
0

使用bash的正則表達式:

while read version; do 
    if [[ $version =~ ^v([0-9]+)\.([0-9]+)(-[^-]+)?-([0-9]+)-(.+) ]]; then 
     echo "${BASH_REMATCH[1]} ${BASH_REMATCH[2]} ${BASH_REMATCH[-2]} ${BASH_REMATCH[-1]} " 
    fi 
done <<END 
v0.1-alpha-3-g9c8c402 
v0.4-beta-10-g3187e7f-dirty 
v1.0-0-fe35119e 
END 
0 1 3 g9c8c402 
0 4 10 g3187e7f-dirty 
1 0 0 fe35119e 

Perl的非捕獲括號(?:...) 也是有用的:

perl -pe 's/^v([0-9]+)\.([0-9]+)(?:-[^-]+)?-([0-9]+)-(.+)/$1 $2 $3 $4/' <<END 
v0.1-alpha-3-g9c8c402 
v0.4-beta-10-g3187e7f-dirty 
v1.0-0-fe35119e 
END 
相關問題