2015-05-22 152 views
3

我正在尋找BASH正則表達式來從下面的命令中拉出'db'粗體。然而,參數的順序並不能保證。出於某種原因,我無法完全工作。正則表達式來匹配行尾

我至今

regex="--db (.*)($| --)" 
[[ [email protected] =~ $regex ]] 
DB_NAMES="${BASH_REMATCH[1]}" 

# These are example lines 
somecommand --db myDB --conf /var/home # should get "myDB" 
somecommand --db myDB anotherDB manymoreDB --conf /home # should get "myDB anotherDB manymoreDB" 
somecommand --db myDB # should get "myDB" 
somecommand --db myDB anotherDB # should get "myDB anotherDB" 

對正則表達式的任何建議?

+0

我不認爲bash支持非貪婪的匹配。你可以嘗試'([^ - ] *)'而不是'(。*)',或者使用awk或sed – Fabricator

+0

爲什麼不使用'getopt'或'getopts'來解析命令行參數? – nanoix9

回答

4

的問題是,使用bashregex的風味不包括非貪婪重複操作符(*?+?)。因爲*是貪婪的,並且沒有辦法告訴它不要貪婪,所以第一個加括號的子表達式((.*))匹配所有行至行尾。

如果您知道要捕獲的值不包含某個字符並將.替換爲排除該字符的字符類,則可以解決此問題。

例如,如果--db後的值不包含破折號(-),你可以使用這個regex

regex='--db ([^-]*)($| --)' 

它張貼在討論的所有示例相匹配。

1

默認情況下,RegEx會嘗試獲得儘可能多的匹配,使用非貪婪(懶惰)量詞。您可能還希望把--第一所以發動機將使用第一

--db[[:space:]](.*?)([[:space:]]--|$) 

Demo


如果你不想 --,你可以使用非捕獲組

--db[[:space:]](.*?)(?:[[:space:]]--|$) 
        ^^ Notice the ?: 

Demo

+1

Bash不支持非貪婪。 –

+2

Bash不支持非捕獲組。 – axiac

0

我想你想匹配上非空格字符趕上第一組:

regex="--db (\S+)(--|$)" 
+0

bash不會使用'\ S'做字符類 - 儘管你不能引用正則表達式。 –

2

以下工作:

regex="--db[[:space:]]([[:alnum:][:space:]]+)([[:space:]]--|$)" 
[[ "[email protected]" =~ $regex ]] 

有兩個問題:

  1. 字符類,如[:空間:]應該是用於表示空格
  2. (.*)是貪婪的,會直到您最近的--文字。由於bash不支持非貪婪匹配,我們必須使用[[:alnum:][:space:]]匹配,這將保證我們在下一個--停止。
+0

它不適用於問題中的前兩個示例。 – axiac

+0

@axiac - 啊,我以爲RegEx是正確的,並且引號引起了問題。修正了正則表達式,謝謝。 –

+0

引號不會造成任何傷害。我運行了問題中發佈的代碼,它適用於最後兩個示例。問題出在前兩個,因爲'bash'使用的'regex'很貪婪,我找不到任何方法(在文檔中)讓它們變得非貪婪。 – axiac