代码之家  ›  专栏  ›  技术社区  ›  elethan

bash regex在ubuntu上匹配,但在macos上不匹配

  •  0
  • elethan  · 技术社区  · 6 年前

    我有以下bash脚本:

    #!/bin/bash
    
    git_status="$(git status 2>/dev/null)"
    branch_pattern="^(# |)On branch ([^${IFS}]*)"
    echo $git_status
    echo $branch_pattern
    
    if [[ ${git_status} =~ ${branch_pattern} ]]; then
        echo 'hello'
        echo $BASH_REMATCH
    fi
    

    下面是我在ubuntu上运行脚本时的输出 bash 版本4:

    On branch master Initial commit Untracked files: (use "git add <file>..." to include in what will be committed) test.sh nothing added to commit but untracked files present (use "git add" to track)
    ^(# |)On branch ([^ ]*)
    hello
    On branch master
    

    但是,当我使用bash version 3在macos上运行相同的脚本时,regex不匹配,并且 if 执行块。其余的输出是相同的。我错过了什么?在这个版本的bash中,我的regex需要在macos/上以不同的格式设置吗?有我不见的国旗吗?

    我也看到过类似的关于跨平台regex行为差异的帖子,例如 find 指挥部,但我还没有找到与我的问题相关的职位。

    2 回复  |  直到 6 年前
        1
  •  1
  •   Gordon Davisson    6 年前

    在我看来,MacOS附带的Bash版本(相当老——3.2.57)的re引擎中有一个bug。这和 ^(# |) 部分——它似乎与字符串开头的空字符串不匹配。但我找到了解决办法。显然如果 ^ 在括号内,如下所示:

    branch_pattern="(^# |^)On branch ([^${IFS}]*)"
    

    顺便说一句,你不应该用 echo $varname 打印变量的内容。首先,它会对值进行分词(将所有空格转换为单个空格)和通配符扩展,这可能会非常混乱/误导。试试像这样的 printf '<<%q>>\n' "$varname" 相反。如果变量包含奇怪的字符,它的输出可能有点神秘,但至少它会清楚地表明 里面有奇怪的东西。

        2
  •  1
  •   Jebby    6 年前

    如果您只想获取当前的git分支名称,则不需要regex。Git已经内置了这个。

    git rev-parse --abbrev-ref HEAD 2>/dev/null

    这将打印出当前分行名称(如果有) 如果您在没有任何提交的git存储库中,它将只返回“head”