2016-09-21 6 views
1

bashスクリプトでフォルダ名を自動完成しようとしています。完全なフォルダ名を入力するとすべてが機能しますが、名前のオートコンプリート方法はわかりません。何か案は?bashスクリプトでオートコンプリート

repo() { 
cd ~/Desktop/_REPOS/$1 
} 

私はアイデアをthis SO postを読んでみましたが、私はまだbashのにかなり新しいですので、すぐに失われてしまいました。

GOAL(私のbashrcに含ま上記のレポ機能付き):

>ls ~/Desktop/_REPOS/ 
folder1 
hellofolder 
stackstuff 

>repo sta[TAB] fills in as: repo stackstuff 

答えて

8

実際にあなたがgeirha's answerからのコードのかなりを借りることができます。

# this is a custom function that provides matches for the bash autocompletion 
_repo_complete() { 
    local file 
    # iterate all files in a directory that start with our search string 
    for file in ~/Desktop/_REPOS/"$2"*; do 
     # If the glob doesn't match, we'll get the glob itself, so make sure 
     # we have an existing file. This check also skips entries 
     # that are not a directory 
     [[ -d $file ]] || continue 

     # add the file without the ~/Desktop/_REPOS/ prefix to the list of 
     # autocomplete suggestions 
     COMPREPLY+=($(basename "$file")) 
    done 
} 

# this line registers our custom autocompletion function to be invoked 
# when completing arguments to the repo command 
complete -F _repo_complete repo 

forループ反復するすべてのファイルで_repo_complete関数の第2引数として与えられた文字列で始まるディレクトリ(これはオートコンプリートされる文字列です)。

.bashrcにコードを追加するとうまくいきます。

+0

私は 'レポ()'関数を削除し、(一つだけの機能を得るために)_repo_complete' '内のコードを配置したい場合、私はそれを行うだろうか? – Rilcon42

+0

最後の行を 'complete -F _repo_complete'に変更できますか? – Rilcon42

+0

オートコンプリートを試みるたびに '_repo_complete'関数が呼び出されるので、これは実用的ではないと思います。あなたはすでに有効なディレクトリ名があるかどうかを調べることでこれをハックしようとするかもしれませんが、私は混乱が1つの関数を保存する価値がないと思います。 – Euro

7

私が正しく理解している場合は、カスタムcdコマンドのパス自動補完という2つのオプションがあります。

  1. あなたのCDPATH環境変数に、~/Desktop/_REPOSを親ディレクトリを追加することができます。

    CDPATH="$CDPATH":"$HOME"/Desktop/_REPOS 
    

    、任意のディレクトリから、あなたはcdスペースタブを入力し、他にすることができます現在のディレクトリのサブディレクトリには、~/Desktop/_REPOSのすべてのディレクトリが表示されます。 (これはまた、この方法の欠点である:より混乱している)

  2. .bashrcに完了機能を追加することができます。あなたが始めたやり方では、すべてのディレクトリのベース名は~/Desktop/_REPOSになります。

    $ compgen -d "$HOME"/Desktop/_REPOS/ 
    /home/me/Desktop/_REPOS/folder1 
    /home/me/Desktop/_REPOS/folder2 
    /home/me/Desktop/_REPOS/stackstuff 
    /home/me/Desktop/_REPOS/hellofolder 
    

    これは、すべてのサブディレクトリの名前を返します:ディレクトリの自動補完を取得するには、我々はcompgen -d組み込みを使用することができます。パスは、より具体的であるとき、それは少数の候補者に還元:

    $ compgen -d "$HOME"/Desktop/_REPOS/f 
    /home/me/Desktop/_REPOS/folder1 
    /home/me/Desktop/_REPOS/folder2 
    

    ベース名以外のすべてを削除するには、次のように我々は、シェルパラメータ展開を使用します。

    $ arr=(/path/to/dir1 /path/to/dir2) 
    $ echo "${arr[@]##*/}" 
    dir1 dir2 
    

    ##*/パラメータ展開では最長を削除しますarrの各要素からの*/の可能性のある一致、すなわち最後のスラッシュの後ろのものだけを残す–私たちが望むもの。

    は、今、私たちは一緒にこれを入れて、関数に:

    _comp_repo() { 
        # Get list of directories 
        # $2 is the word being completed 
        COMPREPLY=($(compgen -d "$HOME"/Desktop/_REPOS/"$2")) 
    
        # Reduce to basenames 
        COMPREPLY=("${COMPREPLY[@]##*/}") 
    } 
    

    これは、一緒にrepoで自動補完のためにそれを使用するための指示で、あなたの.bashrcに入る:

    complete -F _comp_repo repo 
    

    お知らせごrepo関数は、$1引数を引用符で囲んで、特殊文字(スペース、タブ...)でディレクトリ名を正しく処理するようにしてください。

    repo() { 
        cd ~/Desktop/_REPOS/"$1" 
    } 
    

あなたはタブを打った回数はshow-all-if-ambiguousなどreadline settingsに依存します。


参照