logo
Published on

fzf(あいまい検索ツール)でBashコマンドラインを便利に

Authors

あいまい検索、fuzzy finderと呼ばれる機能を備え、それらの機能を利用したコマンド履歴の検索やファイルの選択などの機能を備えるコマンドラインソフトウェア"fzf"で補完(オートコンプリート)や検索を便利にしてみましょう。

インストールは超簡単。

git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
junegunn/fzf: A command-line fuzzy finder Examples · junegunn/fzf Wiki
  • Search syntax

Token Match type Description sbtrkt fuzzy-match Items that match sbtrkt 'wild exact-match (quoted) Items that include wild ^music prefix-exact-match Items that start with music .mp3suffixexactmatchItemsthatendwith.mp3!fireinverseexactmatchItemsthatdonotincludefire!musicinverseprefixexactmatchItemsthatdonotstartwithmusic!.mp3 suffix-exact-match Items that end with .mp3 !fire inverse-exact-match Items that do not include fire !^music inverse-prefix-exact-match Items that do not start with music !.mp3 inverse-suffix-exact-match Items that do not end with .mp3

On multi-select mode (-m), TAB and Shift-TAB to mark multiple items

とりあえず、普通に検索するとあいまい検索になるので、正確な検索をしたい場合は'somethingと検索してやるといいってことぐらいじゃないでしょうか。

では、使い方を紹介していきます。

文字列検索が便利になる

ファイル内検索とかに使えますね。--helpの結果を検索したい、とかに使えます。

cat <<EOT  |fzf
hoge
fuga
foo
EOT
https://yuis.xsrv.jp/images/ss/ShareX_ScreenShot_e7ccf831-fb67-4d93-9250-c2c5f00595aa.gif

コマンド履歴検索が便利になる

fzfの一番便利で手軽な機能はこれでしょう。

ctrl-Rでコマンド履歴が見れるのはご存知かと思いますが、これを便利にしてくれます。

補完(オートコンプリート)が便利になる

fzfのオートコンプリートはtab2回ではなく、**とアスタリスクを二回からのtab、です。

cd **<TAB>
cd ~/github/fzf**<TAB>
head /docker/**<TAB>

ただ普通のオートコンプリートに上書きされているものもあります。それぞれ試してみてください。

kill -9 <TAB>

独自のオートコンプリートの実装

fzfではオリジナルのタブ補完候補を作ることも可能です。

https://yuis.xsrv.jp/images/ss/ShareX_ScreenShot_3b9ecabf-a8be-4a95-8cd1-43a476ec00aa.gif

こんなふうに文字列を指定してやることもできますし、


_fzf_complete_history() {
  _fzf_complete "--multi --reverse" "$@" < <(
    echo very
    echo wow
    echo such
    echo history
  )
}

[ -n "$BASH" ] && complete -F _fzf_complete_history -o default -o bashdefault history

工夫してやればコマンド実行結果を渡してやることも出来ます。便利ですね。

_fzf_complete_sym() {
  _fzf_complete "--multi --reverse" "$@" < <(command ls -1 ${HOME}/sym)
}

[ -n "$BASH" ] && complete -F _fzf_complete_sym -o default -o bashdefault sym

僕が実用しているコード

僕が実際に書いて使っているコードを使用例として載せておきます。

man [commandName]に、高頻度で繋げているスクリプトを補完します。 man bash > ~/tmp.txt && sublime_text ~/tmp.txtみたいになるわけですが、僕はwindows環境からx11フォワーディングでWSLからsublimeでマニュアルページを表示させています。manページはsublimeで見たほうが、コピペにしろ検索にしろ便利というか使い慣れていますので。

_fzf_complete_man() {
  _fzf_complete "--multi --reverse" "$@" < <(
    # view the man pages with sublime via x-server
    echo "> ~/tmp.txt && sublime_text ~/tmp.txt "
  )
}

[ -n "$BASH" ] && complete -F _fzf_complete_man -o default -o bashdefault man

sym [dirname]で、任意のディレクトリの好きなディレクトリへ簡単に移動します。 僕の場合symフォルダにはWindowsファイルシステムのシンボリックリンクをいくつか置いているのですが、主に動画とか音楽とかですね、で、ランダム再生でクラシック聞きたいななんてときにはsym cla**->sym _Classicでディレクトリ移動、で、shufmusic、みたいな感じですね。

https://yuis.xsrv.jp/images/ss/ShareX_ScreenShot_2a83d598-b6cb-41e9-9d3a-7b8efad23996.gif
sym(){

: <<'HELP'
e.g. sym
e.g. sym hinabita
e.g. sym **
HELP

  [ ! -z ${1} ] && cd "${HOME}/sym/${1}" || cd "${HOME}/sym"
}

_fzf_complete_sym() {
  _fzf_complete "--multi --reverse" "$@" < <(command ls -1 ${HOME}/sym)
}

[ -n "$BASH" ] && complete -F _fzf_complete_sym -o default -o bashdefault sym

面白そうなサンプル

コマンド履歴を選択したら即時そのコマンドが実行されます。正直ctrl-Rから選択してenterと効率は変わらないので、わざわざ実装するものでもないかなぁと。ただ組み込みで活用することはできると思います。

# fh - repeat history
fh() {
  eval $( ([ -n "$ZSH_NAME" ] && fc -l 1 || history) | fzf +s --tac | sed 's/ *[0-9]* *//')
}