16

次の bash 補完は、可能な単語 (補完) の配列を compgen に渡します。

basenames=("foo" "fu bar" "baz");

COMPREPLY=($(compgen -W "${basenames[*]}" -- "${COMP_WORDS[COMP_CWORD]}"))

問題は、配列要素の空白が保持されないことです。つまり、「foo bar」は単語分割のおかげで要素として扱われます。4 要素ではなく 3 要素が表示されるように、空白を保持する方法はありますか?

編集

basenamesファイル名が含まれているため、ほぼすべての文字 (/ と \0 を除く) を使用できます。

編集2

-W フラグは、 のような単一の単語を想定していfoo bar foobarます。それに複数の要素を渡す (これは何${basenames[@]}をするか) は機能しません。

編集3

例の basenames 配列を変更しました (そのため、foofoofromfoo barは折りたたまれません)。

改行を使用して単語を区切ることができます。

local IFS=$'\n'
COMPREPLY=($(compgen -W "$(printf "%s\n" "${basenames[@]}")" --  ${COMP_WORDS[COMP_CWORD]}"))

を使用しても、次の\0ことはできません。

local IFS=$'\0'
COMPREPLY=($(compgen -W "$(printf "%s\0" "${basenames[@]}")" --  ${COMP_WORDS[COMP_CWORD]}"))
4

4 に答える 4

11

なぜわざわざcompgen?それらを手動でCOMPREPLYに追加するだけです。以下は、から一致するファイル名を完成させ、/some/pathファイル名を安全に処理します。

some_completion_function() {
    local files=("/some/path/$2"*)
    [[ -e ${files[0]} ]] && COMPREPLY=( "${files[@]##*/}" )
}

compgenファイル名を安全に処理することはできません。

于 2012-07-14T09:26:27.553 に答える
1

おそらくこれは次のようになります。

COMPREPLY=($(compgen -W "$(printf "%q " "${basenames[*]}")" -- "${COMP_WORDS[COMP_CWORD]}"))
于 2012-05-18T18:47:28.583 に答える
-3

ほとんどの場合、アスタリスクの代わりにアット サインを使用して配列に添字を付ける必要があります。

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

からman bash(またはBashリファレンスマニュアルを参照):

下付き文字が@または*の場合、単語は name のすべてのメンバーに展開されます。これらの添え字は、単語が二重引用符で囲まれている場合にのみ異なります。単語が二重引用符で囲まれ${name[*]}ている場合、各配列メンバーの値が IFS 特殊変数の最初の文字で区切られた単一の単語に展開され、${name[@]}name の各要素が個別の単語に展開されます。

つまり、アットマークは配列を「平坦化」します。アスタリスク形式はそれを保持します。

于 2012-05-18T17:32:18.677 に答える