一款開源的檔案搜尋神器,終於不用記 find 命令了

削微寒發表於2022-04-13

這是 HelloGitHub 推出的《講解開源專案》系列,用一篇文章帶你快速上手有趣的開源專案。

今天給大家推薦一個好用+開源的檔案搜尋工具——fd

該工具支援大多數主流作業系統,快來更新你的工具箱感受開源專案帶來的便利吧!

一、fd 簡介

你還在為尋找檔案而煩惱嗎?你還在為記不住 find 一大堆引數而煩惱嗎?那就趕快來看看我這次推薦的專案 fd 吧!

專案地址:https://github.com/sharkdp/fd

官方簡介:A simple, fast and user-friendly alternative to 'find'

我這裡先放一個圖,讓大家直觀地感受下

fd 是一個命令列工具,提供了多種方便的選項進行檔案的搜尋,而且預設是彩色輸出。專案本身是由 Rust 語言編寫的,作為系統級程式語言 Rust 擁有媲美 C++ 的執行速度,那 fd 的速度自然也不在話下,更優秀的是,它提供了強大功能方便使用者按照各種條件進行搜尋。

這個優秀的專案是不是成功地引起了你的注意呢~

二、fd 如何安裝

作為使用的第一步當然是要先安裝啦~

fd 提供了各個作業系統平臺的安裝方式,再不濟可以直接通過原始碼進行安裝(前提是有 Rust 的環境噢)

2.1 一鍵安裝

我這裡以我本地的 Mac 使用 brew 為例

$ brew install fd

brew 也可以一鍵升級

$ brew upgrade fd

具體到各個平臺的詳細安裝方法,你可以看這裡 安裝文件

2.2 原始碼安裝

$ git clone https://github.com/sharkdp/fd.git
$ cd fd
$ cargo install --path .

2.3 檢視幫助

無論哪種方式安裝完成後,就可以直接使用了 -h--help 獲取幫助了,--help 就不演示了,區別就是換成了詳細的幫助說明,如果你以後忘記了某一個引數也記得使用 --help 來檢視哦~

$ fd -h
fd 8.2.1

USAGE:
    fd [FLAGS/OPTIONS] [<pattern>] [<path>...]

FLAGS:
    -H, --hidden            搜尋隱藏的檔案和目錄
    -I, --no-ignore         不要忽略 .(git | fd)ignore 檔案匹配
        --no-ignore-vcs     不要忽略.gitignore檔案的匹配
    -s, --case-sensitive    區分大小寫的搜尋(預設值:智慧案例)
    -i, --ignore-case       不區分大小寫的搜尋(預設值:智慧案例)
    -F, --fixed-strings     將模式視為文字字串
    -a, --absolute-path     顯示絕對路徑而不是相對路徑
    -L, --follow            遵循符號連結
    -p, --full-path         搜尋完整路徑(預設值:僅限 file-/dirname)
    -0, --print0            用null字元分隔結果
    -h, --help              列印幫助資訊
    -V, --version           列印版本資訊

OPTIONS:
    -d, --max-depth <depth>        設定最大搜尋深度(預設值:無)
    -t, --type <filetype>...       按型別過濾:檔案(f),目錄(d),符號連結(l),
                                   可執行(x),空(e)
    -e, --extension <ext>...       按副檔名過濾
    -x, --exec <cmd>               為每個搜尋結果執行命令
    -E, --exclude <pattern>...     排除與給定glob模式匹配的條目
        --ignore-file <path>...    以.gitignore格式新增自定義忽略檔案
    -c, --color <when>             何時使用顏色:never,*auto*, always
    -j, --threads <num>            設定用於搜尋和執行的執行緒數
    -S, --size <size>...           根據檔案大小限制結果。
...

三、fd 快速上手演示

為了能讓之後的演示有一個統一的認識,我這裡新建了一個目錄作為 fd 的測試目錄,我虛構了一些檔案和目錄來模擬實際情況,包括一個隱藏目錄,我之後的演示都會基於該根目錄下,選項如果有短名稱和長名稱,示例中以短名稱為例。

該目錄大致是這樣:

.
├── .hg
│   ├── HelloDjango.md
│   ├── HelloRust.md
│   ├── HelloVue.md
│   ├── HelloZooKeeper.md
├── dir1
│   ├── Hello.java
│   ├── World.java
│   └── dir2
│       ├── demo.py
│       ├── demo1.py
│       ├── dir3
│       │   ├── fd_demo.rs
│       │   └── fd_help.rs
│       └── sss.py
├── hello_fd.md
├── hello_java.md
├── java
│   ├── Hello.java
│   └── World.java
├── my_java.txt
├── python
│   ├── demo.py
│   ├── demo1.py
│   └── sss.py
└── rust
│   ├── fd_demo.rs
│   └── fd_help.rs
├── softdir3 -> dir1/dir2/dir3
└── sss.py -> dir1/dir2/sss.py

3.1 簡單搜尋

fd 直接跟想要搜尋的內容,會遞迴搜尋當前目錄下的所有檔案,列出檔名中包含目標內容的結果(結果為當前目錄的相對路徑)

$ fd Hello
dir1/Hello.java
java/Hello.java

3.2 包含隱藏目錄

選項 -H --hidden

$ fd -H Hello
.hg/HelloDjango.md
.hg/HelloRust.md
.hg/HelloVue.md
.hg/HelloZooKeeper.md
dir1/Hello.java
java/Hello.java

3.3 大小寫

預設 fd 是匹配智慧大小寫的,如果你搜尋的內容是包含大寫會按照大小寫精確匹配,但如果是小寫會忽略大小寫匹配,所以 fd 另外提供了兩種選項來嚴格控制大小寫匹配

選項 -i --ignore-case 忽略大小寫。

$ fd -i Hello
dir1/Hello.java
hello_fd.md
hello_java.md
java/Hello.java

選項 -s --case-sensitive 嚴格匹配大小寫。

$ fd -s hello
hello_fd.md
hello_java.md

3.4 返回絕對路徑

選項 -a --absolute-path

$ fd -a Hello
/Users/junjiexun/fd_test/dir1/Hello.java
/Users/junjiexun/fd_test/java/Hello.java

3.5 返回檔案列表詳情

選項 -l --list-details 獲得類似 ls -l 的效果。

$ fd -l hello
-rw-r--r--  1 junjiexun  staff     0B  3  1 18:42 dir1/Hello.java
-rw-r--r--  1 junjiexun  staff     0B  3  1 18:37 hello_fd.md
-rw-r--r--  1 junjiexun  staff     0B  3  1 18:37 hello_java.md
-rw-r--r--  1 junjiexun  staff     0B  3  1 18:38 java/Hello.java

3.6 搜尋內容包含路徑

選項 -p --full-path 不單單搜尋檔名,還列出目錄中包含目標內容的結果。

因為這個測試的目錄就在 /Users/junjiexun 下面,所以這樣搜尋相當於全部的檔案都會被搜尋出來。

$ fd xun
Nothing return...
$ fd -p xun
dir1
dir1/Hello.java
dir1/World.java
dir1/dir2
...(略)

3.7 包括 .gitignore 裡的檔案

選項 -I --no-ignore 我這裡新建了一個 .gitignore 檔案內容只有一個 *.java 用來演示,並且需要把當前目錄通過 git init 初始化成 git 的專案。

不加該引數,可以看到結果集中 .java 的檔案都被過濾了。

$ fd java
hello_java.md
java
my_java.txt

加上了 -I 之後結果中又包括了 .java 結尾的檔案了。

$ fd -I java
dir1/Hello.java
dir1/World.java
hello_java.md
java
java/Hello.java
java/World.java
my_java.txt

-I 功能我演示完了,為了之後的演示,我將 .gitignore.git 目錄給刪除了。

這些簡單的功能已經可以滿足一半的日常搜尋需求了,接下來我們看看 fd 提供的更高階的搜尋選項吧!

四、高階搜尋選項

4.1 按深度

選項 -d --max-depth <depth>,當前路徑算深度 1,dir3 下面的 rs 檔案就是深度 4 了。

$ fd rs
dir1/dir2/dir3/fd_demo.rs
dir1/dir2/dir3/fd_help.rs
rust/fd_demo.rs
rust/fd_help.rs
$ fd -d 3 rs
rust/fd_demo.rs
rust/fd_help.rs

4.2 按檔案型別

選項 -t --type <filetype>fd 提供了以下幾種 filetype 選項:

  • f:file
  • d:directory
  • l:symlink
  • x:executable
  • e:empty
  • s:socket
  • p:pipe
$ fd -t l
softdir3
sss.py
$ fd -t d
dir1
dir1/dir2
dir1/dir2/dir3
java
python
rust

我給所有的 py 檔案都加了可執行許可權

$ fd -t x
python/demo.py
python/demo1.py
python/sss.py

4.3 按副檔名

選項 -e --extension <ext>

$ fd -e md
hello_fd.md
hello_java.md

4.4 排除

選項 -E --exclude <pattern> 支援萬用字元,排除所有包含字母 s 的結果。

$ fd -E '*s*'
dir1
dir1/Hello.java
dir1/World.java
dir1/dir2
dir1/dir2/demo.py
dir1/dir2/demo1.py
dir1/dir2/dir3
hello_fd.md
hello_java.md
java
java/Hello.java
java/World.java
my_java.txt
python
python/demo.py
python/demo1.py

可以看到所有的 rust、rs、sss、soft 都沒有出現在結果集中。

4.5 按所有者

選項 -o --owner <user:group>

$ fd -l -o junjiexun
drwxr-xr-x  5 junjiexun  staff   160B  3  1 18:42 dir1
-rw-r--r--  1 junjiexun  staff     0B  3  1 18:42 dir1/Hello.java
-rw-r--r--  1 junjiexun  staff     0B  3  1 18:42 dir1/World.java
drwxr-xr-x  6 junjiexun  staff   192B  3  1 18:42 dir1/dir2
-rw-r--r--  1 junjiexun  staff     0B  3  1 18:42 dir1/dir2/demo.py
...(略)

或者 fd -l -o junjiexun:staff 也可以達到同樣的效果,但是 fd 不支援單獨搜尋 group,也不支援萬用字元,如果你有想法的話可以給他提 issue 哦~

4.6 組合命令

fd 提供了 -x--exec <cmd>-X--exec-batch <cmd> 來進行對搜尋結果集的進一步處理

找到所有和 java 匹配的內容並且刪除!(僅僅用做演示,rm -rf 慎用)

$ fd java -X rm -rf

找到所有的 py 並且通過 vim 開啟

$ fd py -X vim

還可以使用諸如 unziplsconvert 等等其他常用的命令,也可以直接使用 *unix 語法 | 管道符語法進一步處理。

4.7 正規表示式

對於檔案的內容搜尋,我之前演示的是諸如 Hello、java、py 都是這樣的完整文字,實際 fd 預設就是支援正規表示式對內容進行搜尋的,但是正規表示式需要使用單引號 ' 包裹起來,我下面演示:將所有 s 開頭的檔案都能被搜尋出來。

$ fd '^s.*'
dir1/dir2/sss.py
python/sss.py
softdir3
sss.py

如果你不想使用正規表示式,想換成更簡單的萬用字元匹配的話就可以使用選項 -g--glob 可以達到同樣的效果。

$ fd -g 's*'
dir1/dir2/sss.py
python/sss.py
softdir3
sss.py

上面的選項大部分都是可以同時使用的,篇幅有限我這裡就不繼續演示了。

五、總結

fd 是一個簡單友好的命令列檔案搜尋工具,而且其開源的屬性作為 Rust 原始碼學習的物件也是非常優秀的,趕緊學起來吧!

《講解開源專案》:https://github.com/HelloGitHub-Team/Article

如果你也對開源專案感興趣,希望自己的文章或專案被更多人喜歡,點選加入《講解開源專案》讓我們一起分享有趣、入門級的開源專案吧!

相關文章