もた日記

くだらないことを真面目にやる

Linuxメモ : Rust製のfdコマンド(findコマンド代替)の使い方

fd

github.com

Rust製のfdはシンプル、高速、ユーザーフレンドリーなfindの代替コマンド。

f:id:wonder-wall:20190306213126p:plain

インストール

各環境でのインストール方法はこのページに書いてある。
バイナリはこのページからダウンロードでき、 Rust製なのでcargo installでインストールできる。

$ cargo install fd-find

ヘルプメッセージ。--helpで長めのヘルプメッセージを表示できる。
findと同様なオプションも多い。

$ fd -h
fd 7.3.0

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

FLAGS:
    -H, --hidden            Search hidden files and directories
    -I, --no-ignore         Do not respect .(git|fd)ignore files
        --no-ignore-vcs     Do not respect .gitignore files
    -s, --case-sensitive    Case-sensitive search (default: smart case)
    -i, --ignore-case       Case-insensitive search (default: smart case)
    -F, --fixed-strings     Treat the pattern as a literal string
    -a, --absolute-path     Show absolute instead of relative paths
    -L, --follow            Follow symbolic links
    -p, --full-path         Search full path (default: file-/dirname only)
    -0, --print0            Separate results by the null character
    -h, --help              Prints help information
    -V, --version           Prints version information

OPTIONS:
    -d, --max-depth <depth>            Set maximum search depth (default: none)
    -t, --type <filetype>...           Filter by type: file (f), directory (d), symlink (l),
                                       executable (x), empty (e)
    -e, --extension <ext>...           Filter by file extension
    -x, --exec <cmd>                   Execute a command for each search result
    -X, --exec-batch <cmd>             Execute a command with all search results at once
    -E, --exclude <pattern>...         Exclude entries that match the given glob pattern
    -c, --color <when>                 When to use colors: never, *auto*, always
    -S, --size <size>...               Limit results based on the size of files.
        --changed-within <date|dur>    Filter by file modification time (newer than)
        --changed-before <date|dur>    Filter by file modification time (older than)

ARGS:
    <pattern>    the search pattern, a regular expression (optional)
    <path>...    the root directory for the filesystem search (optional)

Note: `fd -h` prints a short and concise overview while `fd --help` gives all details.

使い方

基本的な使い方としてはパターンを指定すればカレントディレクトリ以下を検索できる。
デフォルトではsmart case検索となっており、

  • -s: 大文字、小文字を区別する (case sensitive)
  • -i: 大文字、小文字を区別しない(case insensitive)

となる。

$ fd readme
README.md
compat/nedmalloc/Readme.txt
compat/vcbuild/README
$ fd -s readme
$ fd Readme
compat/nedmalloc/Readme.txt
$ fd -i Readme
README.md
compat/nedmalloc/Readme.txt
compat/vcbuild/README

引数なしで検索する

引数なしで実行するとカレントディレクトリ以下のファイル、ディレクトリの一覧が表示できる。

$ fd
COPYING
Documentation
GIT-VERSION-GEN

検索対象ディレクトリを指定する

パターンの後にディレクトリを指定して検索できる。

$ fd passwd /etc
/etc/pam.d/passwd
/etc/passwd
/etc/passwd-
/etc/security/opasswd

正規表現を使用する

正規表現を使用して検索できる。

$ fd '^git.*sh$'
contrib/completion/git-completion.bash
contrib/completion/git-completion.tcsh
contrib/completion/git-completion.zsh
contrib/completion/git-prompt.sh
contrib/fast-import/git-import.sh

拡張子を指定する(-e

-eで拡張子を指定して検索できる。

$ fd readme -e md
README.md
contrib/vscode/README.md

複数指定も可能。

$ fd readme -e md -e txt
README.md
compat/nedmalloc/Readme.txt
contrib/vscode/README.md

シンボリックリンクを辿って検索(-L

-Lでシンボリックリンクを辿って検索できる。

max-depthを指定する(-d

検索するディレクトリの深さを指定する。

$ fd readme -d 2
README.md
contrib/README
gitweb/README
po/README
t/README

ファイルタイプを指定する(-t

-tでファイルタイプを指定。

  • f: ファイル
  • d: ディレクトリ
  • l: シンボリックリンク
  • x: 実行形式ファイル
  • e: 空ファイル/ディレクトリ
$ fd readme -t f  # ファイルのみを検索
README.md
compat/nedmalloc/Readme.txt
compat/vcbuild/README
$ fd -t l  # シンボリックリンクのみを検索
RelNotes

隠しファイル(-H)、ignoreファイル(-I)を対象にする

.で始まる隠しファイルを検索したい場合は-Hを指定する。
また、デフォルトでは.gitignore, .ignore, .fdignoreに書かれてあるパターンを除外するようになっているので、それを無効にしたい場合は-Iを指定する。

$ fd -HI
.git
.clang-format
.editorconfig

除外パターンを指定する(-E

-Eで除外パターンを指定して検索できる。

$ fd readme -E contrib  
README.md
compat/nedmalloc/Readme.txt
compat/vcbuild/README

サイズを指定する(-S

-S<+-><NUM><UNIT>でファイルサイズを指定して検索できる。

$ fd -S -500k # 500KB以下
$ fd -S +1m # 1MB以上

編集日時を指定する

--changed-within, --changed-beforeで編集日時を指定して検索できる。
YYYY-MM-DD HH:MM:SSでの指定や、10h, 1d, 35minといった期間での指定が可能。

$ fd --changed-within '2weeks'
$ fd --changed-within '2019-03-01 00:00:00' 
$ fd --changed-before '2weeks'
$ fd --changed-before '2019-03-01 00:00:00' 

選択したファイルに対してコマンドを実行する

xargsのようなことは-xで実行できる(小文字の-xはそれぞれに対して並列実行、大文字の-Xはまとめて1回だけ実行)。
また、下記のプレースホルダを使用できる。

  • {}: 検索結果のパス (documents/images/party.jpg).
  • {.}: 検索結果のパス(拡張子なし) (documents/images/party).
  • {/}: 検索結果のbasename (party.jpg).
  • {//}: 検索結果の親ディレクトリ (documents/images).
  • {/.}: 検索結果のbasename(拡張子なし) (party).

以下はREADMEにあった使用例。

# jpgファイルをpngファイルに変換
$ fd -e jpg -x convert {} {.}.png

# zipファイルを展開
$ fd -e zip -x unzip

# flacファイルをopusファイルに変換
$ fd -e flac -x ffmpeg -i {} -c:a libopus {.}.opus

# rsファイルの行数をカウント (\;を使ってこのように書くこともできる)
$ fd -x wc -l \; -e rs

fzfと連携する

fzfを使っている場合は以下のような設定を.bashrcなどに追加することでfdを使ってファイルを検索できる。

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

fdの色付き出力を使用したい場合は以下のように設定する。

export FZF_DEFAULT_COMMAND='fd --type file --color=always'
export FZF_DEFAULT_OPTS='--ansi'

f:id:wonder-wall:20190306213752p:plain