Ошибка синтаксиса = ~ в msysgit bash
Я пытаюсь добавить функцию в свой 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: ожидаемый условный двоичный оператор
bash: синтаксическая ошибка около =~'
Из того, что я могу найти, оператор "equals tilde" (=~
) оценивается как regex в bash.
Почему =~
выдает ошибку?
UPDATE: вот скриншот ввода его вручную (на нем запущен sh.exe):
![Screenshot of equals tilde (=~) operator failing]()
Ответы
Ответ 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