什么是bash中的@(... | ... | ...)语法?

时间:2016-03-05 09:14:35

标签: regex bash shell scripting

重点关注此question中提到的@()语法:

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

这种语法来自哪里?为什么在这种情况下使用它?与之有什么不同:

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

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

所有似乎都是等同的。

是否使用此语法代替=~运算符以提高regex的可移植性?

感谢您的澄清

2 个答案:

答案 0 :(得分:5)

extglob中搜索man bash选项:

  

如果使用extglob内置函数启用shopt shell选项,则会识别多个扩展模式匹配运算符。在          在以下描述中,模式列表是由|分隔的一个或多个模式的列表。可以形成复合图案          使用以下一个或多个子模式:

?(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

答案 1 :(得分:2)

这使用man bash模式匹配部分中说明的规则:

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

这使用正则表达式来执行匹配:

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

这些是非常不同的机制,具有不同的性能影响。值darwinfreebsd,...中没有模式,这些是简单的文字字符串。 @(...)语法非常适合这种更简单的匹配逻辑,因此使用正则表达式似乎有点过分。

在这个例子中,两种写作风格都有相同的行为,只是它们通过不同的机制进行匹配。如果不是像darwinfreebsd那样的文字字符串列表,......你有更复杂的正则表达式模式,那么第一种写作风格不是一个选项,你需要使用具有完全正则表达能力的第二个版本。

  

是否使用此语法代替=~运算符以提高regex的可移植性?

使用它是因为它足以达到目的,不需要正则表达式。