`fzf`をインストールしました。次は何をすればいいですか? (2023)
(andrew-quinn.me)- コマンドラインのファジーファインダー
fzfは、投資対効果が即座に現れ、独自の価値を提供しますが、多くの開発者はインストールだけして活用法がわからないまま諦めてしまうツールです Ctrl+Rの履歴検索をファジーマッチングと複数プレビューに置き換えることで、従来の厳密な文字列一致方式の不便さを解消できますAlt+Cならディレクトリ名をうっすら覚えているだけでもファジー cdが可能で、vi $(fzf)の組み合わせでファイルを即座に開けるワークフローを構築できますripgrepとパイプでつなげば、すべてのファイルのすべての行をファジー検索したうえで、そのファイルをすぐエディタで開く高度な使い方も可能です- 既存の Unix ツール(
cat,grep,findなど)を先に習得せよという80/20 ヒューリスティックさえ崩してしまうほど、即効性のある生産性向上ツールです
fzfをインストールした直後に得られる価値
- ソフトウェアエンジニアは自分の仕事を改善するツールを簡単に作れますが、複数のツールを渡り歩きながら深く習得しないままだと、時間が経つほどコストが大きくなります
- 良い 80/20 ヒューリスティックとして、まず
cat,ls,cd,grep,cutのような古典的な Unix ツールを学ぶべきであり、現代的なシステム管理の役割ではsedやawkも含まれます fzfは投資対効果がすぐに現れ、その価値も独特なため、このヒューリスティックの例外と見なせます- 標準的な Ubuntu 環境では、
fzfインストールスクリプトで導入したあと、すぐ使える機能が中核になります
基本ショートカットがもたらす即効性
-
Ctrl+R: コマンド履歴をファジー検索に変える- ほとんどの Linux と Windows のターミナルで、
Ctrl+Rはコマンドの逆方向検索を提供します - 既定の
Ctrl+Rでは、目的のコマンドを見つけるために完全一致が必要で、しかも一度に1つのプレビューしか表示されないため、1文字でも外すと見つけにくくなります fzfをインストールすると、いくつかのキーボードショートカットがより優れた動作に置き換えられ、Ctrl+Rも従来方式より大幅に改善されますaptのようなパッケージマネージャーでインストールした場合、このショートカット統合が提供されないことがあるため、fzfインストールスクリプトを使う理由になります
- ほとんどの Linux と Windows のターミナルで、
-
Alt+C: あいまいな記憶のディレクトリへ素早く移動fzfはAlt+Cを強化版のファジーcdショートカットに変えてくれます- ディレクトリの正確なパスを覚えていなくても、おおよその名前だけで素早く移動できます
- 空のターミナルから、長く訪れていないリポジトリや作業ディレクトリを探すときに便利です
fzf コマンド自体とシェルとの組み合わせ
-
基本の
fzffzfコマンドをそのまま実行すると、現在のディレクトリを基準に相対ファイルパスをファジー検索します- 単体ではファイルの場所を選ぶ程度なので、活用の幅はそれほど大きくありません
-
vi $(fzf)vi $(fzf)のようにコマンド置換と組み合わせると、ファジー検索で選んだファイルをエディタでそのまま開けます- この方法は
viに特有のものではなく、emacs,nano,codeなど好きなエディタと一緒に使えます
-
vi $(find . '/' | fzf)find . '/' | fzfをエディタと組み合わせれば、場所のわからない設定ファイルをフルパス候補からファジー検索して開けますnginx.confのように場所を思い出せないファイルを探すとき、FHS の知識を思い出して推測したり暗記したりする代わりに、findの結果をfzfにパイプすれば済みますconf$のように検索すれば、confで終わる行だけをフィルタできますfindが大量のPermission deniedエラーに遭遇すると、fzfが一時的に不安定になることがありますが、数秒後には回復します- この数秒の遅延は、設定ファイルを非常に単純な方法で見つけられる利便性とのトレードオフです
-
vi **<TAB>sigmonsaysの Hacker News コメントで紹介された機能として、ショートカットの上書きとfzfの直接実行の中間あたりに、アスタリスク2つを使うファジータブ補完がありますvi **<TAB>はvi $(fzf)に近い形でファイル選択に使えます- 実際のコマンドが補完されたあと、さらに
Enterを1回押す必要があります - bash と zsh ではうまく動作しますが、
fishでは動かない場合があります $(fzf)を明示的に呼び出す方法のほうが覚えやすいなら、この機能はあまり使わないかもしれません
ファイル移動にも使える fzf
-
mv $(fzf) $(fzf)mv $(fzf) $(fzf)は、何を移動するかも、どこへ移動するかも正確には覚えていないが、それぞれについてかなり具体的な手がかりだけは覚えているときに使えます- 2回の
fzf選択で、移動元と移動先を決める方式です - GitHub README に GIF を配置する作業のように、ファイルを移動して並べるときによく使いたくなるかもしれません
- 関連例として、
finstemの interactive mode READMEが挙げられています
rg と組み合わせてファイル内容までファジー検索
-
rg: 再帰検索が標準の高速なgrep- 以下の組み合わせは
grepでも可能ですが、rgまたはripgrepは再帰検索が標準のため、この用途では特に強みがあります - 例を試すなら
rgをインストールして使うのが推奨されます
- 以下の組み合わせは
-
rg . | fzfrg .はファイル内の各行を検索結果として出力し、それをfzfに渡すことで、すべてのファイルのすべての行をファジー検索できます- ファイル名ではなく、ファイル内の行内容を手がかりに探す方法になります
-
rg . | fzf | cut -d ":" -f 1rg . | fzfで選んだ結果にcut -d ":" -f 1を付けると、コロン区切りの最初のフィールド、つまりファイルの場所を返せます- 行内容をファジー検索したあと、その行を含むファイルパスだけを得る組み合わせです
-
vim $(rg . | fzf | cut -d ":" -f 1)vim $(rg . | fzf | cut -d ":" -f 1)は、すべてのファイルのすべての行をファジー検索したあと、選んだ行を含むファイルをvimで開く組み合わせです- ファイル名を覚えておらず、内容の一部だけを覚えているときに、そこから直接エディタへ進めます
1件のコメント
Lobste.rs のコメント
この記事の 対象読者 がまさに自分のように思える。fzf をインストールして「天才的だ」と思ったあと、実際に使うのをずっと忘れていたけれど、これでもう使うようになるかもしれない
良い記事ではあるかもしれないが、「これから何をする?」に答えようという目的なら fzf シェル統合 から始めるのは、むしろさらに狭い読者層だけを相手にしている感じがする
bash で ctrl-r を使い慣れているのに、それを置き換えろと言うのは要求レベルが高すぎる。デフォルトを置き換えずに同じ動作を練習する方法から教えてほしかった
ctrl-r はたぶん自分が最もよく使うコマンドで、fzf は学習コストなしですぐにはまる改善だった。ctrl-r で起動するので fzf を使うのを忘れることもない。ただ、その後で Fish shell に移り、そこでは同じ動作がデフォルトで提供されている
納得した。近いうちに fzf と シェル統合 を追加するつもりで、今日は一つ学べた
コマンドに渡すファイルを探すときは
ctrl-tショートカット も使える。特定の変更に含めるファイルを選ぶときにgitと一緒によく使うし、grepの出力結果を絞り込んで検索範囲を狭めるのにも使ったことがあるシェル履歴検索の改善以外にも
fzfを次の 2 つの エイリアス と一緒に使ってきたalias gbd='git -c color.ui=never branch | fzf | xargs -I {} git branch -D {}'主にプルリクエストをマージしたあと、削除するローカルブランチの一覧を選ぶのに使っている。もっと良い方法があるかもしれないが、今のところ失敗したことはない
alias awp='export AWS_PROFILE="$(grep -e "\[\(.*\)\]" ~/.aws/config | sed -e "s/\[//g" | sed -e "s/\]//g" | cut -d " " -f 2 | sort -u | fzf)"'~/.aws/configにある値に応じて AWS_PROFILE をすばやく切り替えられる。今では Kubernetes のネームスペースを切り替える似たようなエイリアスも作ろうかと考えているfzf.vim プラグイン を使えば vim の中で fzf を使える。ファイルを開くだけでなく、バッファ、コマンド履歴、ファイル内容などもファジー検索できる
fzf の主な用途は、線形の Git コミット履歴 をたどって検索し、最近何が変わったのかを把握すること
自分のデフォルトの Git 設定では
git fzfをこう定義している何か見落としている気がする。何をするかも分からないのに、なぜ fzf をインストール するのか気になる
最近の関連投稿もある。あるユーザーが jj 用のファイルセレクタ として fzf を使っている
https://lobste.rs/s/exlogg/jjj