2016-09-28 5 views
1

私はそうのような深いディレクトリ内のログファイルの多くを持っている:私は自分自身がそうのようなさまざまなログを尾行見つけるタブ補完を可能にするエイリアスをbashに追加することはできますか?

/my/deep/path/to/log/files/ 
          foo-2016-10-10.log 
          foo-2016-10-11.log 
          bar-2016-10-10.log 
          bar-2016-10-11.log 

何度も日:

tail -fn 100 /my/deep/path/to/log/files/foo-2016-10-10.log 

はなく、すべてのものを別名することが可能ですが最終的なファイル? そしては、タブの補完によって残りの部分を得ることができますか?例えば

、私は、私はそうのように探している特定のログファイルtl(尾ログの短縮形)を入力してみたい:

$ tl foo 
     [HIT TAB KEY] 
$ tl foo-2016-10-1 
     [HIT 1 and TAB KEY] 
$ tl foo-2016-10-11.log 

はbashで、このことは可能ですか?どうすればこれを達成できますか?

+0

これはプログラミングに関する質問です。**シェルを使用して**についての質問は、SuperUser.comに属します。 – Barmar

+2

このタイプのコマンド補完には一般的にいくつかのスクリプトが必要です。 – chepner

+1

私は別名ではなく、エイリアスではなく関数を使う習慣を得る傾向があります。tl(){ta​​il -fn 100/my/deep/path/to/log/files/"$ 1"; } 'しかし、それはあなたに相当な柔軟性を与えます:例えば、引数を別名で変更することはできませんが、前に付加するだけですが、関数で簡単に行うことができます。 –

答えて

3

_tl_COMPDIR=/my/deep/path/to/log/files/ 
_comp_tl() { 
    local IFS=$'\n' 
    COMPREPLY=($(compgen -f -- "$_tl_COMPDIR$2")) 
    COMPREPLY=("${COMPREPLY[@]#"$_tl_COMPDIR"}") 
} 

tl() (
    cd -- "$_tl_COMPDIR" && tail -fn 100 "[email protected]" 
) 

complete -o nospace -o filenames -F _comp_tl tl 
+0

完全に達成され、非常に簡潔であるが、依然として読める。期待通りに動作します: 'tl' [タブ補完付き]。ありがとうございました。 – Ryan

+0

@gniourf_gniourf、私は私の答え(すなわち、そこにあるコメント)のフィードバックを、それが間違っているという点で聞くことができますか? –

+0

@CharlesDuffy:あなたの答えに何も間違っていない(と私はそれをupvoted)、今あなたがそれを編集しました!最初のバージョンは混乱していましたが、 ':)'です。 –

0

はい、コマンドを実行する前に、単にそのディレクトリに切り替えることができます。

$ cd /my/deep/path/to/log/files/ 
$ tl <tab> 
2

それは少し醜いですが、これは仕事をしていません:あなたのtlについては

_tl_log_path=/my/deep/path/to/log/files 

_tl_completions() { 
    COMPREPLY=("${_tl_log_path}/$2"*) 
    COMPREPLY=("${COMPREPLY[@]#${_tl_log_path}/}") 
    if [[ ${COMPREPLY[0]} = "$2*" ]]; then 
    COMPREPLY=() 
    fi 
} 
complete -F _tl_completions -o filenames tl 

、私はそのように実装することをお勧めしたい:

tl() { 
    # generate an array of arguments to pass to tail 
    local -a args=() 

    # iterate over each argument given to the function 
    for arg; do 
    if [[ -e "$_tl_log_path/$arg" ]]; then 
     # if a like-name file exists under _tl_log_path, add that filename as an argument 
     args+=("$_tl_log_path/$arg") 
    else 
     # otherwise, add that argument exactly as it already exists 
     args+=("$arg") 
    fi 
    done 
    # ...and, finally, execute the tail command. 
    tail -f "${args[@]}" 
} 

。あなたは安くて簡単に行くこともできますが、

tl() (
    cd "$_tl_log_path" || exit 
    exec tail -f "[email protected]" 
) 

説明するために:

  • complete -F funcname cmdnameは、シェル関数funcnameコマンドcmdnameを完了する方法を決定するために呼び出されるべきであることを示しています。 -o filenamesは、結果がファイル名として扱われるべきであることをさらに示している。
  • COMPREPLYは、補完機能が可能な補完で記入することが期待されるシェル配列です。
  • COMPREPLY=("${_tl_log_path}/$2"*)は、指定されたコンテンツをグロブとして展開します(*は意図的に引用符の外にあるため)。
  • COMPREPLY=("${COMPREPLY[@]#${_tl_log_path}/")は、配列内の各結果から接頭辞としてログディレクトリを削除します。 [[ ${COMPREPLY[0]} = "$2*" ]](このときのアスタリスク付き内部引用符)かどうかをチェック
  • 、(したがって)は可能グロブ拡張結果が存在しない場合を検出し、ここでグロブshopt介してそのシェルの構成を仮定し(それ自体に拡大はデフォルトです)。
チャールズ・ダフィーの答えのほとんどのクローン(彼はグロブを使用し、私は compgenを使用している唯一の違い - おそらく補完が(悪い)が書き込まれるように設計されている方法です)
関連する問題