8

大文字と小文字を区別しないことをグローバルに (少なくともそのシェルでは) オンにせずに、特定のコマンドに大文字と小文字を区別しないように指定する方法はありますか?

私の特定のケースでは、電子メール アドレスのデータベースへのコマンド ライン アクセスを可能にする小さなアプリがあるので、次のように入力します。

db get email john smith

John Smith の電子メール アドレスを返します。そのため、アプリ内で主に補完を有効にすることができました: 設定

COMPREPLY=($(compgen -W "$(db --complete $COMP_CWORD "$COMP_WORDS[@]"}")" -- ${COMP_WORDS[COMP_CWORD]}))

タブ補完getemail. ただし、次に入力j<tab>すると拒否されます。これは、電子メールデータベースでは適切に大文字になっているためです。とにかくこれを完了するためにbashを取得したいと思います。(大文字を使用するJと機能します。)

それができない場合は、--completeオプションで入力を一致させることで応答の大文字と小文字を変更することができますが、理想的には、コマンドラインは可能な限りデータベースと一致するはずです。

readlineを使用している場合、アプリ内でこれが機能していることに注意してください。問題と思われるのはbashとのインターフェースのみです。

4

2 に答える 2

6

実際compgen、単語リスト ( ) に対して大文字と小文字を区別しないマッチングを行う方法はないよう-Wです。次の回避策があります。

簡単な解決策: 単語リストと入力トークンの両方を最初にすべて小文字に変換します。注: これは、すべての補完をすべて小文字にすることが許容される場合にのみ使用できるオプションです。

complete_lower() {

    local token=${COMP_WORDS[$COMP_CWORD]}
    local words=$( db --complete $COMP_CWORD "${COMP_WORDS[@]}" )

    # Translate both the word list and the token to all-lowercase.
    local wordsLower=$( printf %s "$words" | tr [:upper:] [:lower:] )
    local tokenLower=$( printf %s "$token" | tr [:upper:] [:lower:] )

    COMPREPLY=($(compgen -W "$wordsLower" -- "$tokenLower"))   
}

より優れた、より精巧な解決策: 大文字と小文字を区別しない独自の一致ロジックを展開します。

complete_custommatch() {

    local token=${COMP_WORDS[$COMP_CWORD]}
    local words=$( db --complete $COMP_CWORD "${COMP_WORDS[@]}" )

    # Turn case-insensitive matching temporarily on, if necessary.
    local nocasematchWasOff=0
    shopt nocasematch >/dev/null || nocasematchWasOff=1
    (( nocasematchWasOff )) && shopt -s nocasematch

    # Loop over words in list and search for case-insensitive prefix match.
    local w matches=()
    for w in $words; do
        if [[ "$w" == "$token"* ]]; then matches+=("$w"); fi
    done

    # Restore state of 'nocasematch' option, if necessary.
    (( nocasematchWasOff )) && shopt -u nocasematch

    COMPREPLY=("${matches[@]}")
}
于 2012-06-11T14:18:14.917 に答える