21

bash_profilefor に関数を追加しようとしています:

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

しかし、次のエラーが表示されます。

bash: 条件付き二項演算子が必要です`

bash: 近くに構文エラーがあります=~'

私が見つけたものから、「等号チルダ」演算子 ( =~) は bash で正規表現として評価されます。

=~エラーがスローされるのはなぜですか?

更新: これは手動で入力するスクリーンショットです (これは sh.exe を実行しています):

等号チルダ (=~) 演算子の失敗のスクリーンショット

4

4 に答える 4

26

WindowsのGitインストールからBash 3.1.0で同じエラーが発生しました。最終的に私はそれを次のように変更しました:

if echo $var | grep -E 'regexp' > /dev/null
then
  ...
fi
于 2013-06-07T15:08:15.303 に答える
7

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 /
于 2013-03-20T07:43:56.017 に答える
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 "username@host.domain" "(.+)@(.+)"; then
    echo ${BASH_REMATCH[0]}
    echo ${BASH_REMATCH[1]}
    echo ${BASH_REMATCH[2]}
fi
于 2015-10-23T09:40:58.027 に答える