bash中括号扩展的等价[[复合命令(测试语句)

时间:2013-09-18 12:09:37

标签: regex bash conditional-operator brace-expansion

我希望foo()符合extended regex或类似brace expansion

基于egrep的解决方案:

foo() 
{
  egrep -sq "$2" <<< "$1" && echo "string '$1' matches pattern '$2'"
}

$ foo bar '.*r'
string 'bar' matches pattern '*r'
$ foo bar '.*r|.*s'
string 'bar' matches pattern '*r|*s'

但我也想要100%bash解决方案。我的尝试:

foo() 
{
  [[ "$1" = $2 ]] && echo "string '$1' matches pattern '$2'"
}

基本模式没问题:

$ foo bar '*r'
string 'bar' matches pattern '*r'

但是,用于检测alternation / extended pattern的适当格式是什么?

$ foo bar '*(r|s)'
$ foo bar '*\(r|s\)'
$ foo bar '*\(r\|s\)'
$ foo bar '*\{r,s\}'
$ foo bar '*{r,s}'

此外bash联机帮助页说:

  

[[表达]]
  不对单词执行单词拆分和路径名扩展   在[[和]]之间;波浪扩展,参数和变量扩展,   算术扩展,命令替换,进程替换和   报价删除被执行。

  1. [[ ]]声明中使用扩展正则表达式/模式是否有诀窍?
  2. 您如何实现此类功能?

2 个答案:

答案 0 :(得分:2)

您需要使用=~运算符。

来自man bash

  

可以使用另外的二元运算符=〜   优先级为==和!=。使用时,右边的字符串   运算符被认为是扩展的正则表达式   并相应地匹配。

试试这个:

foo() 
{
  [[ "$1" =~ $2 ]] && echo "string '$1' matches pattern '$2'"
}

另请注意,*是通配符(并经历“模式匹配”),而.*是正则表达式。

将您的示例更改为:

$ foo bar '.*(r|s)'
string 'bar' matches pattern '.*(r|s)'

答案 1 :(得分:1)

你是说这个?

[[ 'bar' == *[rs] ]] && echo yes || echo no # this is simple globbing

或者使用extglobs:

shopt -s extglob
[[ 'bar' == @(*r|*s) ]] && echo yes || echo no

有关详情,请阅读bash hackers page about pattern matching