我试图添加一个函数到我的bash_profile for msysgit :
function git-unpushed { brinfo=$(git branch -v | grep git-branch-name) if [[ $brinfo =~ ("[ahead "([[:digit:]]*)]) ]] then echo "(${BASH_REMATCH[2]})" fi }
但是我得到以下错误:
bash:有条件的二元运算符预期
bash:语法错误near
=~'
从我能find的,“等于波浪号”运算符( =~
)评估为bash中的正则expression式。
为什么=~
会抛出一个错误?
更新:这是手动input它的屏幕截图(这是运行sh.exe):
更新2015年:msysgit现在已经过时。
你应该使用Git-for-Windows自带的bash。
正如在这个答案中提到的那样,它使用了一个更近的bash(4.3+),为此=~
语法将起作用。
原始答案(2013年3月)
打包msysgit bash可能只是太老,不能完全支持这个运营商。
这当然太旧了 与没有引号的正则表达式进行比较 ,如“ Bash,第3版 ”和“ 如何在bash脚本中使用正则表达式? ”中提到的:
至于Bash的3.2版本,表达式不再引用。
实际上, mklement0在评论中提到:
=~
是在bash 3.0中引入的,并且始终在RHS上支持一个不带引号的标记。
在3.1.x之前,引用的标记与未引用的标记相同,都被解释为正则表达式。
3.2中的变化是,引用的令牌(或引用的令牌的子串)现在被视为文字 。
但我试过用引号(在最新的msysgit 1.8.1.2中),但仍然失败:
vonc@voncvb / $ /bin/bash --version GNU bash, version 3.1.0(1)-release (i686-pc-msys) Copyright (C) 2005 Free Software Foundation, Inc. vonc@voncvb / $ variable="This is a fine mess." vonc@voncvb / $ echo "$variable" This is a fine mess. vonc@voncvb / $ if [[ "$variable" =~ T.........fin*es* ]] ; then echo "ok" ; fi bash: conditional binary operator expected bash: syntax error near `=~' vonc@voncvb / $ if [[ "$variable" =~ "T.........fin*es*" ]] ; then echo "ok" ; fi bash: conditional binary operator expected bash: syntax error near `=~' vonc@voncvb /
我在Windows上从Git安装Bash 3.1.0有同样的错误。 最终我将其改为:
if echo $var | grep -E 'regexp' > /dev/null then ... fi
根据https://groups.google.com/forum/#!topic/msysgit/yPh85MPDyfE这是因为msys不运送libregex与bash。 据说如果你编译/找到一个MSYS内置libregex,并把它放在库路径, =~
开始工作正常。
这是一个解决方案,支持提取匹配的字符串。 如果运算符=〜不受bash支持,则使用sed命令(使用msysgit安装)
if eval "[[ a =~ a ]]" 2>/dev/null; then regexMatch() { # (string, regex) eval "[[ \$1 =~ \$2 ]]" return $? } elif command -v /bin/sed >/dev/null 2>&1; then regexMatch() { # (string, regex) local string=$1 if [[ ${2: -1} = $ ]]; then local regex="(${2%$})()()()()()()()()$" else local regex="($2)()()()()()()()().*" fi regex=${regex//\//\\/} local replacement="\1\n\2\n\3\n\4\n\5\n\6\n\7\n\8\n\9\n" local OLD_IFS=$IFS IFS=$'\n' BASH_REMATCH=($(echo "$string" | /bin/sed -rn "s/$regex/$replacement/p" | while read -r; do echo "${REPLY}"; done)) IFS=$OLD_IFS [[ $BASH_REMATCH ]] && return 0 || return 1 } else error "your Bash shell does not support regular expressions" fi
用法示例:
if regexMatch "username@host.domain" "(.+)@(.+)"; then echo ${BASH_REMATCH[0]} echo ${BASH_REMATCH[1]} echo ${BASH_REMATCH[2]} fi