Подтвердить что ты не робот

Ошибка синтаксиса = ~ в msysgit bash

Я пытаюсь добавить функцию в свой bash_profile для :

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

Но я получаю следующую ошибку:

bash: ожидаемый условный двоичный оператор

bash: синтаксическая ошибка около =~'

Из того, что я могу найти, оператор "equals tilde" (=~) оценивается как regex в bash.

Почему =~ выдает ошибку?

UPDATE: вот скриншот ввода его вручную (на нем запущен sh.exe):

Screenshot of equals tilde (=~) operator failing

4b9b3361

Ответ 1

Обновление 2015: msysgit теперь устарел.
Вы должны использовать bash, который поставляется с git-for-windows.
Как упоминалось в этом ответе, он использует гораздо более свежий bash (4.3+), для которого синтаксис =~ будет работать.


Оригинальный ответ (март 2013 г.)

bash, упакованный в msysgit, может быть слишком старым, чтобы полностью поддерживать этот оператор.
Это, конечно, слишком старый для сравнения с нерекованным регулярным выражением, как указано в " Bash, версия 3" и "Как использовать регулярные выражения в bash скриптах?":

Начиная с версии 3.2 из Bash выражение, которое больше не цитируется.

Собственно, mklement0 упоминает в комментариях:

=~ был введен в bash 3.0 и всегда поддерживал нецитированный токен на RHS.
До 3.1.x цитируемые жетоны обрабатывались так же, как и некотируемые токены: оба они интерпретировались как регулярные выражения.
То, что было изменено в 3.2, заключалось в том, что цитируемые жетоны (или цитируемые подстроки токена) теперь рассматриваются как литералы.

Но я пробовал с кавычками (в последнем 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] /

Ответ 2

У меня была такая же ошибка при установке Bash 3.1.0 из Git в Windows. В конечном итоге я изменил его на:

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

Ответ 3

В соответствии с https://groups.google.com/forum/#!topic/msysgit/yPh85MPDyfE это связано с тем, что msys не отправляет libregex вместе с bash. Предположительно, если вы компилируете/находите встроенный libregex и размещаете его в пути к библиотеке, =~ начинает нормально работать.

Ответ 4

Вот решение, которое поддерживает извлечение совпадающих строк. Если оператор = ~ не поддерживается 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