Bashオートコンプリート:他のディレクトリのファイルとディレクトリの一覧表示

Bashオートコンプリート:他のディレクトリのファイルとディレクトリの一覧表示

prpsls私はディレクトリにファイルを作成または編集するスクリプトを作成しました~/proposals

これで自動補完スクリプトを作成しており、クリックして次のように設定しようとしています。商標、現在の作業ディレクトリに関係なく、completeディレクトリ内のファイルとディレクトリを一覧表示する組み込み機能です。~/proposals

私が達成したい動作は私が行ったのとまったく同じですcomplete -f prpslsが、現在のディレクトリのファイルとディレクトリを一覧表示するのではなく、常にディレクトリの内容を完了したいと思います~/proposals

たとえば、私が書くlsとき商標、次を示します。

$ pwd
/home/user/base_directory
$ ls
file_01   file_02    subdir_01/

私がsubd書いた商標、次のように自動的に完了しますsubdir_01商標繰り返しますが、これが示すものですdir_01

$ ls subdir_01/
file_03    subdir_02/

私が探している行動は次のとおりです。

$ pwd
/home/user/any/directory/it/should/not/matter
$ prpsls # Tab here
proposal_01    proposal_02    job_01/
$ prpsls job_01/ # Tab again
proposal_03    proposal_draft

complete私の質問は:組み込み機能でこの動作は可能ですか?そうでなければ、どのようにこの動作を達成できますか?

completeデフォルトディレクトリとして使用するディレクトリをフラグで知ることができたらと思いますが、ディレクトリリストを生成する-dwhichと同じディレクトリ関連フラグのみが表示されます-A directory

興味深いことに、私がcompgen -f "~/proposals/"使うならする次の場所のファイルとディレクトリのリスト~/proposals:

$ pwd
/home/user/any/directory/it/should/not/matter
$ compgen -f "~/proposals/"
~/proposals/job_01
~/proposals/proposal_01
~/proposals/proposal_02

私は見たこれしかし、質問は次のとおりです。

  • 許可された回答は、入れ子になったディレクトリでは機能しません。 (つまり商標ディレクトリの内容を表示します。)
  • 答えはCDPATH他のコマンドにもっと混乱をもたらすでしょう。
  • 答えはcompgenネストされたディレクトリでも機能しません。

答え1

に基づいてこの素晴らしい答えfooファイルとディレクトリを再帰的に完成するコマンドに対して、次の完成を作成しました~/foodir

FOO_DIR=$HOME/foodir/

_foo_compgen_filenames() {
    local cur="$1"

    # Files, excluding directories:
    grep -v -F -f <(compgen -d -P ^ -S '$' -- $FOO_DIR"$cur") \
        <(compgen -f -P ^ -S '$' -- $FOO_DIR"$cur") |
        sed -e 's|^\^'$FOO_DIR'||' -e 's/\$$/ /'

    # Directories:
    compgen -d -S / -- $FOO_DIR"$cur" | sed -e 's|'$FOO_DIR'||'
}

_foo_complete() {
    local cur=${COMP_WORDS[COMP_CWORD]}
    COMPREPLY=( $(_foo_compgen_filenames "$cur") )
}

complete -o nospace -F _foo_complete foo

秘密は、compgen完成エンジンが完成からファイルへのフルパスを完了するようにしてFOO_DIRから、FOO_DIR完成からそのパスを送信する前に削除することですcomplete。また、ディレクトリ名の末尾にスラッシュを追加する問題もあります。これは指定されておらず、compgenファイルのみを返す基本的な方法はありません(ただし、ディレクトリのみを返す方法は実際にはあります)。

答え2

私はそれを修正する方法についていくつかの方法とアイデアを試してみました。

専門家は私の方法を改善し、より良い/完璧なソリューションを作成できます。

私のシステムは、KDEとGNOMEを含むDebian GNU / Linux 10(buster)4.19.0-16-amd64です。

最初の部分:

  1. 新しいシェルの起動

  2. 作業ディレクトリを作成して/home/user/ComBash入力cdします。

  3. mytabコマンド全体にバインドするスクリプトを作成します。

    これで、mytab次のようになります。

    #!/bin/bash
    echo "MYTAB"
    
  4. chmod +x mytab

  5. px完全なコマンド用の2番目のスクリプトの作成

    これで、px次のようになります。

    #/usr/bin/env bash
    echo "PX"
    
  6. chmod +x px

  7. pxそれではスクリプトを始めましょう。

    source px
    

    または

    ./px
    

    または

    . ./px
    

    出力は「PX」でなければなりません(動作する)。

  8. bin/名前が次の新しいフォルダを作成します。/home/user/ComBash

    mkdir bin
    

    私たちのファイルは今

    mytab        | script
    px           | script
    bin/         | folder
    
  9. 次に、workdirパスmytabにインストールして削除します。bin//home/user/ComBash/binmytab/home/user/ComBash/

    install mytab bin/mytab && rm mytab
    
  10. 次に、bin/workdir フォルダを追加します。$PATH

    PATH="/home/user/ComBash/bin:${PATH}"
    

    または

    PATH="${PATH}:/home/user/ComBash/bin"
    

    確認してください

    echo $PATH 
    
  11. mytab動作していることを確認してください。

    • myt+TABを押してEnter
    • mytab~によるとEnter
    • 出力は「MYTAB」です(動作)。
  12. フォルダ内にフォルダ、サブフォルダ、および空のファイルを作成します。TAB+が有効であることをTAB確認し、TAB | TABに表示される内容を確認するには、これらのフォルダとファイルが必要です。

これで、2番目の部分の構造が完成しました。ソリューションは現在のシェルでのみ機能します。

新しいシェルを閉じて起動すると/home/user/ComBash/bininが$PATH削除され、bashはmytabスクリプトを見つけることができません/home/user/ComBash/bin。これにより、新しいシェルが起動するたびに手順9($ PATH設定)を繰り返す必要があります。

シェルを起動するたびに手順9を繰り返さない場合は、永久に追加できます/home/user/ComBash/bin$PATH

2番目の部分:

  1. pxファイルのオープンと編集

    私もこのコマンドをたくさん試しましたが、今は説明しません。結果を表示しようとします。試したい行のコメントを削除して編集します。

    今pxは次のようになります:

    #/usr/bin/env bash
    #complete -f mytab
    #complete -D -F "/home/user/ComBash" mytab
    #complete -W "$(find /home/user/ComBash/ -path "" -prune -o \( -type d -ls \) -o \( -type f -ls \) | cut -d/ -f 5-)" mytab
    #complete -W "$(find /home/user/ComBash/ -path "" -prune -o \( -type d -ls \) -o \( -type f -ls \) | cut -d/ -f 2- | sed 's/$/\//')" mytab
    #complete -W "$(find /home/user/ComBash/ -path "" -prune -o \( -ls \)))" mytab
    #complete -W "$(ls -R ${MYPATH} | grep /)" mytab
    MYPATH="/home/user/ComBash/"
    complete -W "$(ls -R ${MYPATH})" mytab
    

    コマンド全体をmytabスクリプトにバインドします。

    -W完全な単語リストを提供することを意味します。

    我々はとして単語のリストを取得しますls -R

    ls -R指定されたパスのすべてのファイル、サブファイル、ディレクトリ、およびサブディレクトリを一覧表示します。

  2. pxスクリプトを起動します

    source px
    

    スクリプト内に変更があるたびにスクリプトを再起動する必要があります(パート1のステップ6を参照)。

    source px 
    
  3. 今私たちが使うシェルから

    mytab+TAB

    /home/user/ComBash/指定されたパス()内のすべてのファイル、サブファイル、ディレクトリ、およびサブディレクトリのリストを表示できます。

    すべてのファイル、サブファイル、ディレクトリ、およびサブディレクトリを選択し、[TAB]を使用してオートコンプリートできます。

    有効なサブフォルダを選択して[TAB]を押します。

    押すと、Enterスクリプトはmytab「MYTAB」をエコーし​​ます。

  4. mytabでスクリプトを編集しましょう/home/user/ComBash/bin

    これで、mytab次のようになります。

    #!/bin/bash
    MYPATH=/home/user/ComBash
    # echo $MYPATH
    echo $1
    DATA=$(find ${MYPATH} -name ${1})
    echo $DATA
     ####### DO SOMETHING #######
    

    $1pxスクリプト検索で受け取ったフォルダやファイルを出力し、DATAそのPATHフォルダやファイルの内容を出力します。

これで、現在のファイルまたはフォルダに対して特定のタスクを実行できます。

mytab+Tab押すEnter

関連情報