在bash中的if-condition中使用正则表达式

时间:2010-02-27 18:02:32

标签: regex bash

我想知道在bash的if子句中使用正则表达式的一般规则?

这是一个例子

$ gg=svm-grid-ch  
$ if [[ $gg == *grid* ]] ; then echo $gg; fi  
svm-grid-ch  
$ if [[ $gg == ^....grid* ]] ; then echo $gg; fi  
$ if [[ $gg == ....grid* ]] ; then echo $gg; fi  
$ if [[ $gg == s...grid* ]] ; then echo $gg; fi  
$   

为什么最后三个不匹配?

希望你能提供尽可能多的一般规则,而不仅仅是这个例子。

5 个答案:

答案 0 :(得分:119)

使用glob模式时,问号代表单个字符,星号代表零个或多个字符的序列:

if [[ $gg == ????grid* ]] ; then echo $gg; fi

使用正则表达式时,圆点表示单个字符,星号表示前面字符的零个或多个。因此,“.*”表示任何字符中的零个或多个,“a*”表示零个或多个“a”,“[0-9]*”表示零个或多个数字。另一个有用的(在许多中)是加号,它代表前面一个或多个字符。所以“[a-z]+”表示一个或多个小写字母字符(在C语言环境中 - 以及其他一些字符串)。

if [[ $gg =~ ^....grid.*$ ]] ; then echo $gg; fi

答案 1 :(得分:35)

使用     =〜

用于正则表达式检查Regular Expressions Tutorial Table of Contents

答案 2 :(得分:13)

if [[ $gg =~ ^....grid.* ]]

答案 3 :(得分:7)

为那些对更易于使用的解决方案感兴趣的人grep和基本sh内置函数添加此解决方案(独立于bash版本;也适用于普通的sh,非Linux平台等。)

# GLOB matching
gg=svm-grid-ch    
case "$gg" in
   *grid*) echo $gg ;;
esac

# REGEXP    
if echo "$gg" | grep '^....grid*' >/dev/null ; then echo $gg ; fi    
if echo "$gg" | grep '....grid*' >/dev/null ; then echo $gg ; fi    
if echo "$gg" | grep 's...grid*' >/dev/null ; then echo $gg ; fi    

# Extended REGEXP
if echo "$gg" | egrep '(^....grid*|....grid*|s...grid*)' >/dev/null ; then
  echo $gg
fi    

某些grep版本也支持-q(安静)选项,作为重定向到/dev/null的替代选项,但重定向也是最便携的。

答案 4 :(得分:3)

@OP,

  

glob pettern不仅用于文件名吗?

不,“glob”模式不仅用于文件名。你用它来比较字符串。在您的示例中,您可以使用case / esac来查找字符串模式。

 gg=svm-grid-ch 
 # looking for the word "grid" in the string $gg
 case "$gg" in
    *grid* ) echo "found";;
 esac

 # [[ $gg =~ ^....grid* ]]
 case "$gg" in ????grid*) echo "found";; esac 

 # [[ $gg =~ s...grid* ]]
 case "$gg" in s???grid*) echo "found";; esac

  

在bash中,何时使用glob模式以及何时使用正则表达式?谢谢!

正则表达式比“glob glob”更通用,更“方便”,但是除非你正在完成“globbing / extended globbing”无法轻松提供的复杂任务,否则不需要使用正则表达式。 bash< 3.2(如dennis所提到的)版本不支持正则表达式,但你仍然可以使用扩展通配(通过设置extglob)。对于扩展的globbing,请参阅here和一些简单示例here

OP的更新:查找以2个字符开头的文件的示例(点“。”表示1个字符),然后使用正则表达式“g”

例如输出

$ shopt -s dotglob
$ ls -1 *
abg
degree
..g

$ for file in *; do [[ $file =~ "..g" ]] && echo $file ; done
abg
degree
..g

在上面,文件是匹配的,因为它们的名称包含2个字符后跟“g”。 (即..g)。

与globbing的等价物将是这样的:(查看reference了解?*的含义

$ for file in ??g*; do echo $file; done
abg
degree
..g