ripgrep / fd / fzf で爆速検索:モダンなターミナル検索ツール入門

よるほろぐ編集部

· 約 20 分

ターミナルでファイルやテキストを探すとき、長年 grep -rfind . -name に頼ってきた方は多いと思います。これらは POSIX 標準ツールとして枯れた信頼性がある一方、大きなリポジトリを再帰検索すると待ち時間が発生したり、デフォルトで .gitignore を尊重しないためビルド成果物まで引っかかったりと、開発ツールとして使うには少々もどかしい面があります。

そこで登場するのが ripgrepfdfzf の3つです。それぞれの役割を一言でまとめると:

  • rg(ripgrep) … テキスト検索grep -r の代替。Rust 製で並列処理、.gitignore を自動で尊重
  • fdファイル検索find の代替。直感的なシンタックス、スマートケース、.gitignore を自動で尊重
  • fzf対話的ファジー絞り込み。パイプで何でも受け取り、インタラクティブに選択できる汎用フィルター

この3つを使いこなすと、コードベース内の検索やファイル選択が快適になります。それぞれの基本から、組み合わせ技まで順に見ていきましょう。

インストール

Ubuntu / Debian

# ripgrep(コマンド名は rg)
sudo apt install ripgrep

# fd(パッケージ名は fd-find、コマンド名は fdfind)
sudo apt install fd-find

# fzf
sudo apt install fzf
Ubuntu での fd コマンド名

Ubuntu / Debian では fd というバイナリ名は別パッケージが使用しているため、fd-find パッケージのコマンド名は fdfind になります。fd として使いたい場合は以下のようにシンボリックリンクを作成してください。

mkdir -p ~/.local/bin
ln -s $(which fdfind) ~/.local/bin/fd
# ~/.local/bin が $PATH に含まれていることを確認

Fedora / RHEL 系

sudo dnf install ripgrep fd-find fzf

Fedora では fd-find パッケージでもコマンド名は fd になるため、Ubuntu のようなシンボリックリンク作業は不要です。

macOS(Homebrew)

brew install ripgrep fd fzf

Cargo(すべてのプラットフォーム共通)

Rust の cargo がインストールされていれば、どの環境でも同じコマンド名でインストールできます。

cargo install ripgrep fd-find
# fzf は Go 製なので cargo でのインストールは非対応
# → Homebrew や公式バイナリを使う

ripgrep(rg)

ripgrep はテキストを再帰的に検索する、grep -r の高速な代替ツールです。Rust の正規表現エンジンによる並列検索と、デフォルトで .gitignore・隠しファイル・バイナリファイルを除外する自動フィルタリングが特徴です。

基本的な使い方

# カレントディレクトリ以下から "TODO" を検索
rg TODO

# 特定のファイルを検索
rg "エラー" app.log

# 特定のディレクトリを検索
rg "useState" ./src

実行イメージ(マッチしたファイル名・行番号・該当行が色付きで出力されます):

src/components/App.tsx
42:  const [count, setCount] = useState(0);

src/hooks/useData.ts
7:  const [data, setData] = useState(null);

grep と違い、-r--include も不要で、そのまま使えます。

よく使うオプション早見表

オプション意味
-i大文字・小文字を無視rg -i todo
-Sスマートケース(小文字のみなら大文字無視)rg -S Todo
-F正規表現を無効化(固定文字列として検索)rg -F "std::cout"
-w単語境界に一致するもののみrg -w log
-t TYPEファイルタイプで絞り込むrg -t py "def main"
-T TYPEファイルタイプを除外rg -T js "TODO"
-g GLOBglob パターンで対象を指定rg -g "*.rs" "fn main"
-uu隠しファイル・無視ファイルも検索rg -uu "secret"
-r TEXT出力中のマッチを置換表示(ファイルは変更しない)rg "foo" -r "bar"
-C Nマッチ前後 N 行をコンテキストとして表示rg -C 3 "panic"
-lマッチしたファイル名だけを表示rg -l "TODO"
-cマッチした行数をファイルごとに表示rg -c "error"
-n行番号を表示(デフォルトで有効)rg -n "main"

使用可能なファイルタイプは rg --type-list で確認できます。

よく使うコマンド例

# Python ファイルだけを検索
rg -t py "import os"

# node_modules を除いて検索(glob で除外)
rg -g "!node_modules" "TODO"

# マッチ周辺 2 行も表示
rg -C 2 "panic" ./src

# マッチした行数が多いファイルを把握
rg -c "console.log" | sort -t: -k2 -rn | head

# .env など隠しファイルも検索(-uu で二重に制限解除)
rg -uu "API_KEY"

# 出力置換プレビュー(ファイルは変更しない)
rg "http:" -r "https:" config.txt

grep との比較表

やりたいことgrepripgrep
ディレクトリ再帰検索grep -r "foo" .rg "foo"
大文字小文字を無視grep -ri "foo" .rg -i "foo"
行番号付きgrep -rn "foo" .rg "foo"(デフォルト)
特定拡張子のみgrep -r --include="*.py" "foo" .rg -t py "foo"
ファイル名だけ表示grep -rl "foo" .rg -l "foo"
単語境界grep -rw "log" .rg -w "log"
.gitignore を尊重git grep "foo" / 手動除外rg "foo"(デフォルト)

fd

fd は find の使いやすい代替ツールです。デフォルトでスマートケース(小文字のみのパターンは大文字小文字を区別しない)、.gitignore を尊重、カラー出力と、手元の開発作業に向いたデフォルト設定になっています。

基本的な使い方

# カレントディレクトリ以下から "config" を含む名前を検索
fd config

# 特定のディレクトリを検索
fd main /usr/local

# 引数なしでカレントディレクトリのすべてのエントリを表示
fd

実行イメージ:

src/config.ts
tests/config.spec.ts
docs/configuration.md

find . -name '*config*' と比べて、パターン部分だけ書けばよく、前後の * が不要です。

よく使うオプション早見表

オプション意味
-e EXT拡張子で絞り込むfd -e rs
-H隠しファイル・ディレクトリも検索fd -H .env
-I.gitignore を無視して検索fd -I target
-t fファイルのみfd -t f main
-t dディレクトリのみfd -t d src
-gglob パターンで検索(デフォルトは正規表現)fd -g "*.json"
-x CMD各結果に対してコマンドを実行(並列)fd -e jpg -x convert {} {.}.png
-X CMD全結果をまとめて1回コマンドに渡すfd -g "test_*.py" -X vim
-d N探索の深さを N に制限fd -d 2 config
-pファイル名でなくフルパスにマッチfd -p ".git/config"
-E PATTERN除外パターンfd -E node_modules
-lls -l 形式で詳細表示fd -e rs -l

よく使うコマンド例

# すべての Rust ファイルを列挙
fd -e rs

# 隠しファイルも含めて .env を探す
fd -H .env

# ファイルのみ、深さ 3 まで
fd -t f -d 3

# すべての *.log を削除(-X rm で一括)
fd -e log -X rm

# すべての *.jpg を *.png に変換
fd -e jpg -x convert {} {.}.png

# テストファイルをまとめて vim で開く
fd -g "test_*.py" -X vim

-x は各ファイルに対して並列でコマンドを実行し、-X はすべてのファイルをまとめて1回のコマンドに渡します。find . -exec の使いやすい代替として覚えておくと便利です。

find との比較表

やりたいことfindfd
ファイル名を再帰検索find . -name '*config*'fd config
拡張子で検索find . -name '*.rs'fd -e rs
ファイルのみfind . -type f -name '*.txt'fd -t f -e txt
ディレクトリのみfind . -type d -name srcfd -t d src
隠しファイルも検索find . -name '.env'fd -H .env
各ファイルにコマンド実行find . -name '*.bak' -exec rm {} \;fd -e bak -X rm
深さ制限find . -maxdepth 2 -name '*.conf'fd -d 2 -e conf
.gitignore を尊重git ls-files / 手動除外fd(デフォルト)

fzf

fzf(fuzzy finder)はパイプで受け取ったリストをインタラクティブにファジー絞り込みできる汎用フィルターです。ファイル選択、コマンド履歴、プロセス選択など、リスト系の操作を対話的にする「接着剤」として機能します。

基本的な使い方

fzf はパイプ入力を受け取り、ファジー検索 UI を起動します。選択した項目が stdout に出力されます。

# すべてのファイルを fzf で選択して vim で開く
vim $(fzf)

# 特定のコマンド出力を fzf で選択
ps aux | fzf

# 複数選択して xargs に渡す(-m で複数選択可能)
fd -e ts | fzf -m | xargs vim

ファジー検索の文法

入力中にスペースで区切ることで AND 検索になります。特殊プレフィックスも使えます:

トークンマッチの種類説明
fooファジーマッチfoo を含む(順不同で文字が含まれる)
'exact完全一致exact を含む
^prefix前方一致prefix で始まる
suffix$後方一致suffix で終わる
!fire除外fire を含まない

プレビューウィンドウ

--preview オプションで、選択候補のプレビューを横に表示できます。{} が選択中のアイテムに置換されます。

# bat でファイルの中身をプレビュー(bat がない場合は cat でも可)
fd -e md | fzf --preview 'bat --color=always {}'

# cat を使ったシンプルなプレビュー
fd -t f | fzf --preview 'cat {}'

# ディレクトリの中身をプレビュー
fd -t d | fzf --preview 'ls -lA {}'

シェル統合(キーバインド)

fzf の真骨頂はシェルへの統合です。インストール後に以下の設定をシェルの設定ファイルに追加するとキーバインドが有効になります。

# ~/.bashrc に追加
eval "$(fzf --bash)"

# ~/.zshrc に追加(zsh の場合)
source <(fzf --zsh)

有効になるキーバインド:

キー動作
Ctrl-Tカレントディレクトリ以下のファイルを fzf で選択してコマンドラインに挿入
Ctrl-Rコマンド履歴を fzf でインタラクティブに検索・挿入
Alt-Cディレクトリを fzf で選択して cd
シェル統合と FZF_DEFAULT_COMMAND の関係

FZF_DEFAULT_COMMAND はシェル統合(Ctrl-T / Alt-C)では 使われません。シェル統合には専用の変数が用意されています:

  • FZF_CTRL_T_COMMANDCtrl-T で使うコマンド
  • FZF_ALT_C_COMMANDAlt-C で使うコマンド

FZF_DEFAULT_COMMAND が有効なのは、fzf を stdin なしで直接起動した場合(例: vim $(fzf))のみです。

組み合わせワークフロー

3つのツールを組み合わせると、検索から選択・実行までのフローが大幅にスムーズになります。

rg の結果を fzf で絞り込んでエディタで開く

# rg でテキスト検索 → fzf で候補選択 → vim で開く
vim $(rg -l "TODO")

# rg の出力(ファイル名:行番号:内容)を fzf に渡して選択
rg --line-number "TODO" | fzf --delimiter=: --nth=1,3.. \
  --preview 'bat --color=always {1} --highlight-line {2}'

fd + fzf でファイルを探して開く

# fd でファイル列挙 → fzf でプレビュー付き選択 → vim で開く
vim $(fd -t f | fzf --preview 'bat --color=always {}')

# Rust ファイルに絞って探す
vim $(fd -e rs | fzf --preview 'cat {}')

環境変数の設定

# ~/.bashrc / ~/.zshrc に追加

# fzf を直接起動したとき(vim $(fzf) など)に fd を使う
export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'

# Ctrl-T でのファイル検索にも fd を使う
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"

# Alt-C でのディレクトリ移動にも fd を使う
export FZF_ALT_C_COMMAND='fd --type d --hidden --follow --exclude .git'

# プレビューをデフォルトで付ける
export FZF_CTRL_T_OPTS="--preview 'bat --color=always {}'"

実用的なシェル関数・エイリアス

以下を ~/.bashrc または ~/.zshrc に貼り付けることで、ターミナルの検索ワークフローが一段快適になります。

# ===== ~/.bashrc / ~/.zshrc に追加 =====

# rg + fzf: テキスト検索結果を選んでエディタで開く
# 使い方: rgf <検索パターン>
rgf() {
  local file line
  read -r file line < <(
    rg --line-number --no-heading "$1" \
      | fzf --delimiter=: --nth=1,3.. \
            --preview 'bat --color=always --highlight-line {2} {1}' \
      | awk -F: '{print $1, $2}'
  )
  [[ -n "$file" ]] && ${EDITOR:-vim} +"$line" "$file"
}

# fd + fzf: ファイルをプレビューしながら選んで開く
# 使い方: ff [拡張子]
ff() {
  local file
  file=$(fd ${1:+-e "$1"} --type f \
    | fzf --preview 'bat --color=always {}')
  [[ -n "$file" ]] && ${EDITOR:-vim} "$file"
}

# fd + fzf: ディレクトリを選んで cd
# 使い方: fcd
fcd() {
  local dir
  dir=$(fd --type d | fzf --preview 'ls -lA {}')
  [[ -n "$dir" ]] && cd "$dir"
}

# fzf で git ブランチを選んで checkout
# 使い方: fbr
fbr() {
  local branch
  branch=$(git branch --all | fzf | sed 's|remotes/origin/||' | tr -d '* ')
  [[ -n "$branch" ]] && git checkout "$branch"
}

ワークフローのまとめ

flowchart LR
  A["テキスト検索\nrg PATTERN"] --> B["fzf で候補絞り込み"]
  C["ファイル検索\nfd PATTERN"] --> B
  B --> D["エディタで開く\nvim / code"]
  B --> E["パイプで次のコマンドへ\nxargs / rm / mv"]

まとめ

  • rg(ripgrep)… grep -r の高速代替。.gitignore を尊重し、-t でファイルタイプ絞り込みも手軽
  • fdfind の直感的な代替。スマートケース・カラー出力・-x/-X でのコマンド実行が便利
  • fzf … 何でもインタラクティブにするファジーフィルター。--preview とシェル統合(Ctrl-TCtrl-RAlt-C)で作業効率が大きく上がる

3つを組み合わせたシェル関数を一度設定しておけば、大規模なコードベースでも目的のファイルやテキストにすばやくたどり着けます。


出典

共有: X でシェア はてブ

編集・検証

よるほろぐ編集部

Linux・コンテナ・CLI・開発環境の実践ガイドを編集・検証します。

編集方針を読む