ファイル名マッチングパターン問題のbashプログラム可能な完了

ファイル名マッチングパターン問題のbashプログラム可能な完了

という簡単なコマンドがありますth。以下のbash完了ファイルがあります。

_th()  {
  COMPREPLY=()
  local curr=${COMP_WORDS[COMP_CWORD]}
  COMPREPLY=( $(compgen -f -X '!*.@(tar|tar.xz|tar.bz2|tar.gz|tbz|tgz)' -- "$curr") )
}                
complete -F _th -o filenames th

ほとんどの場合、これは期待どおりに機能します。私のth関数引数の場合、BASHは、で終わるファイルに対してのみタブ補完を使用します.tartar.xz2つの質問を待っています。

  1. 一致は大文字と小文字を区別します。すべてのtarファイルに小文字の拡張子があるわけではありません。 (bash完成ファイルでshoptsetを使用してnocaseglobも効果はありません。)

  2. 一致は、名前にスペースが含まれるファイルなど、複数の単語で構成されるファイル名をブロックします。

    [rsaw:blahb]$ ls
    bam.tgz  boom.TGZ  sad.TAR  spaces in this-file.tbz
    [rsaw:blahb]$ th<tabtab>
    bam.tgz        in             spaces         this-file.tbz  
    [rsaw:blahb]$ th spa<tabtab>
    in             spaces         this-file.tbz  
    [rsaw:blahb]$ th spaces<tabtab>   # At this point I added a backslash and pressed tab until 4 backslashes appeared
    in             spaces         this-file.tbz  
    [rsaw:blahb]$ th spaces\\\\<tabtab>   # At this point, nothing else happened 
    

助けてくれてありがとう!

答え1

これがまだ問題であるかどうかはわかりませんが、中国語の字幕ファイル名を完成させ、考えられる解決策についていくつかのアイデアを得ることを試みたときに同様の問題が発生しました。

IFSファイル名にスペースが含まれる問題を修正して変数を変更しようとするlocal IFS=$'\n'価値があるかもしれません。

大文字と小文字を区別したくない場合は、$currcompgenを使用してcompgenを小文字に強制することができます${cur,,}。 2つの変更後の全体的な機能は次のとおりです。

_th()  {
  local IFS=$'\n'
  local curr=${COMP_WORDS[COMP_CWORD]}
  COMPREPLY=( $(compgen -f -X '!*.@(tar|tar.xz|tar.bz2|tar.gz|tbz|tgz)' -- "${curr,,}") )
}                
complete -F _th -o filenames th

これにより、ファイル名全体が大文字と小文字を区別しなくなります。拡張子から大文字と小文字を区別しない場合は、文字列操作で拡張子を小文字にするだけ$curです。

答え2

正規表現を使用してファイル形式拡張子で実行できる操作は2つあります。すべて大文字の拡張子を正規表現に直接追加できます。つまり、検索時に大文字と小文字を区別しないようにフラグを(tar|TAR)追加できます。?iこのガイドを参照してください。https://stackoverflow.com/questions/43632/can-you-make-just-part-of-a-regex-case-insensitive

したがって、複数の単語の完成に関する別の答えは次のとおりです。https://stackoverflow.com/questions/1146098/properly-handling-spaces-and-quotes-in-bash-completion (私は個人的にこの理由ですべてのファイルでスペースの代わりに_を使用します)

関連情報