2016-03-05 133 views
4

把重點放在@()語法在此question mentionned:不熟悉語法

[[ $OSTYPE == *@(darwin|freebsd|solaris|cygwin|openbsd)* ]]

哪裏這句法從何而來?爲什麼在這種情況下使用?而且是用什麼區別:

[[ $OSTYPE =~ (darwin|freebsd|solaris|cygwin|openbsd) ]]

[[ $OSTYPE == *(darwin|freebsd|solaris|cygwin|openbsd) ]]

,一切都似乎等價物。

此語法是否用於代替=~運算符,以便使用正則表達式實現更好的可移植性?

感謝您的澄清

+0

可能的重複:[如何在unix/linux shell中進行模式匹配時使用反向或負向通配符?](http://stackoverflow.com/a/217208/3776858) – Cyrus

+0

@Cyrus我的問題是'爲什麼使用這種語法'比'如何得到結果'。 – SLePort

+0

謝謝@choroba。因此,與「COMP_TYPE」無關,也沒有列表完成...上面的例子是從bash完成代碼中提取的,這對我造成了困惑。 – SLePort

回答

2

這使用規則在模式說明匹配的man bash部分:

[[ $OSTYPE == *@(darwin|freebsd|solaris|cygwin|openbsd)* ]]

這使用正則表達式來執行匹配:

[[ $OSTYPE =~ (darwin|freebsd|solaris|cygwin|openbsd) ]]

這些是非常不同的機制,具有不同的性能影響。值darwinfreebsd,...中沒有模式,這些是簡單的文字字符串。 @(...)語法對於這種更簡單的匹配邏輯來說是完美的,所以使用正則表達式看起來有點過分。

在這個例子中,兩種書寫風格都給出相同的行爲,只是它們通過不同的機制來執行匹配。如果不是像darwinfreebsd,......這樣的文字字符串列表,您有更復雜的正則表達式模式,那麼第一個寫作風格將不是一個選項,您將需要使用具有完整正則表達式的第二個版本。

此語法是否用於代替=~運算符,以便使用正則表達式實現更好的可移植性?

它被使用,因爲它是足夠好的目的,正則表達式不需要。

+0

它也用於幾行後面的正則表達式'local mansect =「@([0-9lnp] | [0-9] [px] | 3?(gl | pm))」。 ' – SLePort

+0

這不是一個正則表達式。將shell通配符模式與正則表達式混淆是常見的錯誤,因爲它們看起來很相似。這個你給出的例子在解析爲shell通配符和正則表達式時會有不同的解釋。 – janos

+0

你說得對。兩個錯誤+一個重複。這不是我的一天( - ; – SLePort

3

搜索man bashextglob選項:

如果extglob外殼選項使用shopt內置啓用,幾個擴展模式匹配運營商的認可。在 下面的描述中,模式列表是由|分隔的一個或多個模式的列表。複合模式可以使用以下子圖案中的一個或多個來形成 :

?(pattern-list) 
    Matches zero or one occurrence of the given patterns 
*(pattern-list) 
    Matches zero or more occurrences of the given patterns 
+(pattern-list) 
    Matches one or more occurrences of the given patterns 
@(pattern-list) 
    Matches one of the given patterns 
!(pattern-list) 
    Matches anything except one of the given patterns