代码之家  ›  专栏  ›  技术社区  ›  Tim unnamed eng

在bash的if条件中使用正则表达式

  •  78
  • Tim unnamed eng  · 技术社区  · 15 年前

    我想知道在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 回复  |  直到 6 年前
        1
  •  113
  •   Superole    12 年前

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

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

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

    if [[ $gg =~ ^....grid.*$ ]] ; then echo $gg; fi
    
        2
  •  33
  •   PersianGulf    10 年前

    使用 =

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

        3
  •  12
  •   Ignacio Vazquez-Abrams    15 年前
    if [[ $gg =~ ^....grid.* ]]
    
        4
  •  7
  •   vladr    15 年前

    添加此解决方案 grep 基础 sh 为那些对更便携的解决方案感兴趣的人提供的内置组件(独立于 bash 版本;也适用于普通的旧版本 ,在非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    
    

    一些 小精灵 化身也支持 -q (安静)选项,作为重定向到 /dev/null ,但重定向仍然是最可移植的。

        5
  •  3
  •   Tim Visée ghostdog74    6 年前

    @奥普,

    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模式,何时使用正则表达式?谢谢!

    regex比“glob模式”更加通用和“方便”,但是除非您正在执行“globbing/extended globbing”无法轻松提供的复杂任务,否则不需要使用regex。 bash<3.2版本不支持regex(正如dennis提到的),但是您仍然可以使用扩展的globbing(通过设置 extglob )有关扩展的全局搜索,请参见 here 还有一些简单的例子 here .

    Op更新:使用regex查找以2个字符(点“.”表示1个字符)后跟“g”的文件的示例

    EG输出

    $ 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