fzf 常用指令指南

1. fzf 是什麼?

fzf 是一個通用的命令列模糊搜尋工具。

它可以接收任何文字清單,例如:

接著讓你透過互動式介面搜尋並選取其中一筆或多筆資料。官方將它描述為一個適用於任何清單的互動式過濾器。

fzf 最重要的概念是:

產生清單的指令 | fzf | 後續處理

例如:

git branch | fzf

流程是:

git branch
    ↓
產生 branch 清單
    ↓
fzf 讓使用者搜尋並選擇
    ↓
輸出選中的 branch

2. 安裝 fzf

Ubuntu / Debian

sudo apt update
sudo apt install fzf

確認版本:

fzf --version

官方提供 APT 作為 Debian 與 Ubuntu 的安裝方式。

安裝最新版

Linux 套件庫中的版本有時較舊,也可以透過官方 Git repository 安裝:

git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install

安裝程式會協助設定 $PATH、快捷鍵和 Shell completion。


3. 第一個 fzf 指令

建立一個簡單清單:

printf "development\nstaging\nproduction\n" | fzf

畫面中輸入:

prod

按下 Enter 後,fzf 會輸出:

production

可以把結果存進變數:

environment=$(printf "development\nstaging\nproduction\n" | fzf)

echo "$environment"

fzf 會從標準輸入讀取清單,並將選中的項目輸出到標準輸出。


4. 基本操作快捷鍵

進入 fzf 介面後:

快捷鍵 功能
直接輸入文字 搜尋
Ctrl + J / Ctrl + N 往下移動
Ctrl + K / Ctrl + P 往上移動
Enter 選擇目前項目
Esc / Ctrl + C 離開
Tab 多選模式下標記項目
Shift + Tab 取消或反向標記

多選需要加上 --multi-m

printf "apple\nbanana\norange\n" | fzf --multi

使用 Tab 選取多個項目,再按下 Enter


5. 最重要的 Shell 整合

只使用 command | fzf 還不算真正發揮 fzf。

最值得先學的是下面三個快捷鍵:

Ctrl + R    搜尋指令歷史
Ctrl + T    搜尋檔案或目錄
Alt + C     搜尋並切換目錄

Zsh 設定

將以下內容加入:

~/.zshrc
# Enable fzf key bindings and fuzzy completion
source <(fzf --zsh)

重新載入設定:

source ~/.zshrc

Bash 設定

加入 ~/.bashrc

eval "$(fzf --bash)"

這種整合方式適用於近期版本的 fzf;舊版本可能需要載入安裝目錄中的個別 Shell scripts。


6. Ctrl + R:搜尋指令歷史

在 Terminal 按下:

Ctrl + R

fzf 會列出之前執行過的指令。

例如輸入:

docker log

可能找到:

docker logs -f backend-api

按下 Enter 後,指令會被貼回目前的命令列,可以修改後再執行。

這通常是 fzf 最實用的功能。你不再需要一直按方向鍵尋找以前執行過的指令。

在歷史搜尋畫面中再次按下 Ctrl + R,可以切換相關性與時間排序。


7. Ctrl + T:搜尋檔案

先輸入部分指令:

vim

接著按下:

Ctrl + T

選擇檔案後,fzf 會將路徑貼到命令列:

vim src/components/UserProfile.tsx

也可以搭配其他指令:

cat

按下 Ctrl + T

cat README.md

或者:

rm

按下 Ctrl + T

rm dist/old-file.js

Ctrl + T 的作用是將選中的檔案或目錄路徑貼到目前的命令列。


8. Alt + C:快速切換目錄

直接按下:

Alt + C

搜尋目錄名稱,例如:

backend

選擇後會自動執行類似:

cd ~/projects/company/backend-api

這比下面的操作快很多:

cd ~/projects
ls
cd company
ls
cd backend-api

Alt + C 會搜尋目錄並切換至選中的目錄。

部分 Terminal 或作業系統可能攔截 Alt + C。遇到這種情況,可以嘗試:

Esc

放開後再按:

C

9. ** + Tab 模糊補全

fzf 的 Shell integration 還提供模糊 completion。

搜尋檔案

輸入:

vim **<Tab>

也就是先輸入:

vim **

接著按下 Tab

fzf 會開啟檔案選擇介面。

搜尋指定目錄下的檔案

vim src/**<Tab>

搜尋上層目錄

vim ../**<Tab>

切換目錄

cd **<Tab>

搜尋 SSH Host

ssh **<Tab>

搜尋並終止 Process

kill -9 **<Tab>

預設 completion trigger 是 **。Shell integration 對檔案、目錄、PID、SSH hostname、環境變數與 alias 提供相應的模糊補全。


10. fzf 搜尋語法

fzf 不只是單純包含文字搜尋。

假設有以下檔案:

src/user-service.ts
src/user-controller.ts
test/user-service.test.ts
docs/user-service.md

模糊搜尋

輸入:

usrsvc

即使字元不連續,也可能找到:

src/user-service.ts

精確包含

'user-service

搜尋包含 user-service 的項目。

必須以指定文字開始

^src

只顯示以 src 開頭的項目。

必須以指定文字結束

.ts$

只顯示以 .ts 結尾的項目。

排除指定文字

!test

排除包含 test 的項目。

組合條件

^src .ts$ !controller

代表:

以 src 開頭
而且以 .ts 結尾
而且不能包含 controller

OR 搜尋

.ts$ | .tsx$

顯示 .ts.tsx 檔案。

fzf 預設使用 extended search;空格分隔的條件會組合搜尋,^ 表示開頭、$ 表示結尾、! 表示排除,單獨的 | 可作為 OR。


11. 將 fzf 與其他指令組合

選擇檔案

find . -type f | fzf

使用 Vim 開啟選中的檔案

vim "$(find . -type f | fzf)"

比較穩健、能處理特殊檔名的版本:

fzf --print0 | xargs -0 -o vim

官方也建議在需要可靠處理檔名時使用 null-separated output 搭配 xargs -0

搜尋環境變數

env | fzf

搜尋目前 Process

ps -ef | fzf

選擇 Git branch

git branch --format='%(refname:short)' | fzf

直接切換:

git switch "$(git branch --format='%(refname:short)' | fzf)"

比較安全的 function:

gbs() {
    local branch

    branch=$(git branch --format='%(refname:short)' | fzf) || return

    git switch "$branch"
}

將它加入 ~/.zshrc 後,可以執行:

gbs

選擇 Git commit

git log --oneline --decorate | fzf

查看選中的 commit:

commit=$(git log --oneline | fzf | awk '{print $1}')

[[ -n "$commit" ]] && git show "$commit"

Kubernetes Pod

kubectl get pods | fzf

查看選中 Pod 的 log:

klog() {
    local pod

    pod=$(kubectl get pods \
        --no-headers \
        -o custom-columns=':metadata.name' |
        fzf) || return

    kubectl logs -f "$pod"
}

12. 加入預覽視窗

假設已安裝 bat

sudo apt install bat

Ubuntu 某些版本的執行檔名稱可能是:

batcat

可以建立 alias:

alias bat='batcat'

使用 bat 預覽檔案:

git ls-files |
fzf --preview 'bat --style=numbers --color=always --line-range :300 {}'

其中:

{}

代表目前游標選中的項目。

也可以使用一般工具:

git ls-files |
fzf --preview 'sed -n "1,200p" {}'

不要將只能處理檔案的 preview 指令直接放進所有情境共用的 FZF_DEFAULT_OPTS,因為 fzf 也可能接收 process、history 或一般文字;官方特別提醒這會造成非檔案輸入時的錯誤。


13. 建議的基本外觀設定

~/.zshrc 加入:

# Enable fzf shell integration
source <(fzf --zsh)

# Default appearance
export FZF_DEFAULT_OPTS='
  --height=40%
  --layout=reverse
  --border
'

# Ignore large or unnecessary directories
export FZF_CTRL_T_OPTS='
  --walker-skip .git,node_modules,target,dist,.next
'

export FZF_ALT_C_OPTS='
  --walker-skip .git,node_modules,target,dist,.next
'

重新載入:

source ~/.zshrc

--height 會讓 fzf 只占用 Terminal 的部分高度;--layout=reverse 會將搜尋欄顯示在上方;--border 則加入邊框。這些選項可以透過 FZF_DEFAULT_OPTS 設成全域預設。


14. 搭配 fd 提升檔案搜尋體驗

fzf 本身是互動式篩選器,不是專門的檔案索引工具。

可以搭配 fd

sudo apt install fd-find

Ubuntu 的指令名稱有時是:

fdfind

查看是否存在:

command -v fd
command -v fdfind

建立 alias:

alias fd='fdfind'

設定 fzf 使用 fd 產生檔案清單:

export FZF_DEFAULT_COMMAND='fd --type f --strip-cwd-prefix'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"

包含隱藏檔、追蹤 symbolic link,但排除 .git

export FZF_DEFAULT_COMMAND='
  fd
  --type f
  --strip-cwd-prefix
  --hidden
  --follow
  --exclude .git
'

官方建議搭配 fdripgrep 產生遵守 .gitignore 的檔案清單。


15. 建議的學習順序

第一階段只需要熟悉三個快捷鍵:

Ctrl + R    找以前執行過的指令
Ctrl + T    找檔案
Alt + C     切換目錄

第二階段理解核心模式:

command | fzf

例如:

git branch | fzf
ps -ef | fzf
env | fzf
kubectl get pods | fzf

第三階段開始把常用操作包成 Shell function:

gbs
klog

第四階段再學:

--preview
--multi
--bind
FZF_DEFAULT_OPTS
fd
ripgrep
tmux popup

16. 五分鐘練習

練習一:基本選擇

seq 100 | fzf

搜尋:

42

練習二:多選

seq 20 | fzf --multi

使用 Tab 選擇多個數字。

練習三:搜尋檔案

find . -type f | fzf

練習四:搜尋指令歷史

按下:

Ctrl + R

尋找以前執行過的 Git、Docker 或 kubectl 指令。

練習五:Git branch 切換

git switch "$(git branch --format='%(refname:short)' | fzf)"

快捷鍵速查

Ctrl + R       搜尋指令歷史
Ctrl + T       搜尋檔案或目錄
Alt + C        搜尋並切換目錄
Ctrl + J/N     往下
Ctrl + K/P     往上
Enter          確認
Esc            離開
Tab            多選
Shift + Tab    取消或反向選擇
** + Tab       模糊補全

核心觀念

資料來源 | fzf | 後續處理

fzf 本身不需要知道資料是檔案、Process、Git branch 還是 Kubernetes Pod。只要前面的指令能輸出文字清單,fzf 就能讓你互動式搜尋與選擇。


相關文件