2013-03-19 91 views
21

我想要的功能添加到我的bash_profile語法錯誤=〜運營商msysgit慶典

function git-unpushed { 
    brinfo=$(git branch -v | grep git-branch-name) 
    if [[ $brinfo =~ ("[ahead "([[:digit:]]*)]) ]] 
    then 
     echo "(${BASH_REMATCH[2]})" 
    fi 
} 

,但我得到了以下錯誤:

bash: conditional binary operator expected`

bash: syntax error near =~'

從什麼我可以發現,「等於波浪號」運算符(=~)在bash中評估爲正則表達式。

爲什麼=~會引發錯誤?

更新:這是手動輸入它的截圖(這是運行sh.exe):

Screenshot of equals tilde (=~) operator failing

+0

無需引用或放正則表達式括號內,只使用例如'[[$ line =〜^ $]]' –

+0

好,你是什麼樣的?什麼是'/ bin/sh'符號鏈接? –

+0

@FredrikPihl:由於這是在'bash_profile',我懷疑有一個家當。 – ruakh

回答

7

更新2015年:msysgit現在已經過時。
你應該使用自帶的bash git-for-windows
正如this answer中所述,它使用更近的bash(4.3+),其中=~語法將工作。


原來的答覆(2013年3月)

與msysgit包裝bash的可能僅僅是太老了,完全支持這種操作。
這當然是太舊不帶引號的正則表達式進行比較,如 「Bash, version 3」 和 「How do I use regular expressions in bash scripts?」 中提到:其實

As of version 3.2 of Bash, expression to match no longer quoted.

mklement0提到的評論:

=~ was introduced in bash 3.0 and always supported an unquoted token on the RHS.
Up to 3.1.x, quoted tokens were treated the same as unquoted tokens: both were interpreted as regexes.
What changed in 3.2 was that quoted tokens (or quoted substrings of a token) are now treated as literals.

但我試過用引號(在最新的msysgit 1.8.1.2中),它仍然失敗:

[email protected]/
$ /bin/bash --version 
GNU bash, version 3.1.0(1)-release (i686-pc-msys) 
Copyright (C) 2005 Free Software Foundation, Inc. 
[email protected]/
$ variable="This is a fine mess." 
[email protected]/
$ echo "$variable" 
This is a fine mess. 
[email protected]/
$ if [[ "$variable" =~ T.........fin*es* ]] ; then echo "ok" ; fi 
bash: conditional binary operator expected 
bash: syntax error near `=~' 
[email protected]/
$ if [[ "$variable" =~ "T.........fin*es*" ]] ; then echo "ok" ; fi 
bash: conditional binary operator expected 
bash: syntax error near `=~' 
[email protected]/
+1

重新「太舊,不能未加引號的正則表達式來比較」:'=〜'在bash的3.0引入_always_支持在RHS的_unquoted_令牌。截至3.1.X,_quoted_令牌被_treated的same_爲加引號標記:兩者都解釋爲正則表達式。 3.2中改變的是_quoted_標記(或標記的引用子字符串)現在被視爲_literals_。 – mklement0

+0

@ mklement0好點。我已將您的評論納入答案中,以獲得更多的知名度。 – VonC

+0

我很感激,謝謝。 – mklement0

26

我在Bash 3.1.0上從Git安裝在Windows上有同樣的錯誤。最終,我把它改爲:

if echo $var | grep -E 'regexp' > /dev/null 
then 
    ... 
fi 
+9

這適用於簡單情況,但不適用於捕獲組。 – Eris

13

根據https://groups.google.com/forum/#!topic/msysgit/yPh85MPDyfE這是因爲MSYS不使用bash沿船長libregex。據說如果你編譯/找到一個msys構建libregex,並把它放在庫路徑中,=~開始工作正常。

+1

偉大的指針。不幸的是,簡單地用MSYS中的一個替換msysgit的'msys-regex-1.dll'不會奏效。什麼是_seem_工作(自負風險),是將以下文件從MSYS安裝的bin目錄複製到msysgit的bin目錄:bash.exe,sh.exe,msys-termcap -0.dll' - 換句話說:完全取代bash。但是,那時你可能直接使用MSYS,只使用msysgit中的'git.exe' - 請參閱http://stackoverflow.com/q/5885393/45375 – mklement0

1

這是一個支持提取匹配字符串的解決方案。如果運營商=〜不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 "[email protected]" "(.+)@(.+)"; then 
    echo ${BASH_REMATCH[0]} 
    echo ${BASH_REMATCH[1]} 
    echo ${BASH_REMATCH[2]} 
fi 
+2

請注意,沒有人再使用msygit:它現在已經過時並替換爲git-for-windows(https://github.com/git-for-windows/git/releases),它有一個更近的bash 4.x(http://stackoverflow.com/a/26826359/6309) – VonC

+0

哇,我不後悔切換到Linux。 –

+0

@Vonc在處理了一段時間的這種瘋狂之後(我想我在8月第一次遇到它),我只是把git-for-windows用於旋轉,並且吹走了它修復了多少愚蠢的煩惱與msysgit (例如缺乏vim的智能默認,缺少可調整大小的終端等)。我想我在2011年或2012年開始使用msysgit,並不知道有什麼更好的(也許當時沒有?)。老實說,我不知道爲什麼這個建議被埋在評論中 - 也許你應該考慮讓它成爲答案?恕我直言,這是這裏最好的答案。 –