我正在尝试为msysgit的bash_profile
添加一个函数:
function git-unpushed {
brinfo=$(git branch -v | grep git-branch-name)
if [[ $brinfo =~ ("[ahead "([[:digit:]]*)]) ]]
then
echo "(${BASH_REMATCH[2]})"
fi
}
但是我收到以下错误:
bash:条件二元运算符expected`
bash:
=~'
附近的语法错误
根据我的发现,“equals tilde”运算符(=~
)在bash中评估为正则表达式。
为什么=~
会抛出错误?
更新:这是手动输入的截图(这是运行sh.exe):
答案 0 :(得分:26)
我在Windows上的Git安装上遇到了与Bash 3.1.0相同的错误。最终我改为:
if echo $var | grep -E 'regexp' > /dev/null
then
...
fi
答案 1 :(得分:13)
根据https://groups.google.com/forum/#!topic/msysgit/yPh85MPDyfE,这是因为msys没有随bash一起发布libregex。据说如果你编译/找到一个msys构建的libregex,并把它放在库路径中,=~
就可以正常工作了。
答案 2 :(得分:7)
2015年更新:msysgit现已过时
您应该使用 git-for-windows 附带的bash
正如this answer中所提到的,它使用了更新的bash(4.3+),=~
语法将起作用。
原始答案(2013年3月)
使用msysgit打包的bash可能太旧而无法完全支持此运算符
与未加引号正则表达式进行比较肯定太旧了,如" Bash, version 3"和" How do I use regular expressions in bash scripts?":
自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 /
答案 3 :(得分:1)
这是一个支持提取匹配字符串的解决方案。如果bash不支持operator =〜,则使用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