⚙️

想像以上に調査捗るfindコマンド

2021/02/06に公開

はじめに

findコマンド誰でも使ったことがあるとは思いますが、毎回調べて使う、というのもかなり面倒でそのコマンドの良さにも中々に気付きづらい。せいぜい調査する時探したい情報がある時やShellScriptなどを書いている時に実現したいことがあって欲しい機能だけ調べて使い、忘れるを繰り返しているのだと思います(というか自分がそうです)。findコマンドの細かいオプションを知らないことで、脳死でそれぞれのディレクトリにアクセスして探していくという非効率的なことをやっていたり、それを知らないが故許容していたりします。実はこういう作業は大体コマンドを覚えてさえいれば一瞬で解決できたりします。

尚、基本的に文字は少な目にし「見たら分かるねん」を心がけております。

使い方

基本この形にオプションを追加して条件を絞り込む形

$ find <dir_name> [<option>, ...]

ディレクトリ構造

今回findコマンドを使うにあたり例として用いるディレクトリ構造は以下

$ tree .

.
├── README.md
├── env
│   ├── dev
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   ├── prod
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   ├── task_definition
│   │   │   ├── container.tpl
│   │   │   ├── migration.json
│   │   │   └── nginx.tpl
│   │   ├── terraform.tfvars
│   │   ├── terraform.tfvars.sample
│   │   ├── user_data
│   │   │   └── server.sh
│   │   └── variables.tf
│   └── stg
│       ├── main.tf
│       ├── outputs.tf
│       └── variables.tf
└── module
    ├── acm
    │   ├── main.tf
    │   ├── outputs.tf
    │   └── variables.tf
    ├── alb
    │   ├── main.tf
    │   ├── outputs.tf
    │   └── variables.tf
    ├── ecr
    │   ├── main.tf
    │   ├── outputs.tf
    │   └── variables.tf
    ├── network
    │   ├── main.tf
    │   ├── outputs.tf
    │   └── variables.tf
    ├── route53
    │   ├── main.tf
    │   ├── outputs.tf
    │   └── variables.tf
    ├── server
    │   ├── main.tf
    │   ├── outputs.tf
    │   └── variables.tf
    └── storage
        ├── main.tf
        ├── outputs.tf
        └── variables.tf

ユースケース

指定したディレクトリのPATHを一覧表示したい

$ find <dir_name>
$ find env
env
env/prod
env/prod/outputs.tf
env/prod/main.tf
env/prod/user_data
env/prod/user_data/server.sh
env/prod/variables.tf
env/prod/task_definition
env/prod/task_definition/container.tpl
env/prod/task_definition/migration.json
env/prod/task_definition/nginx.tpl
env/dev
env/dev/outputs.tf
env/dev/main.tf
env/dev/variables.tf
env/stg
env/stg/outputs.tf
env/stg/main.tf
env/stg/variables.tf

name | tplファイルどこに保存したっけ、、、

$ find . -name "*.tpl"

./env/prod/task_definition/container.tpl
./env/prod/task_definition/nginx.tpl

type | ディレクトリだけ表示したい

typedを使います。

-type
   b block special
   c character special
   d directory
   f regular file
   l symbolic link
   p FIFO
   s socket

$ find . -type d

.
./module
./module/network
./module/alb
./module/ecr
./module/server
./module/storage
./module/acm
./module/route53
./env
./env/prod
./env/prod/user_data
./env/prod/task_definition
./env/dev
./env/stg

! and name | tfファイル以外で何保存してたっけ、、、

-nameで検索したい対象の文字列を入力すると検索対象を絞り込むことができます。
-inameでcase insensitiveな検索ができる(つまり、大文字小文字関係なく検索可能)
!を付けると否定で絞り込むことができます。
fをつけてファイルで絞り込まないと余計なディレクトリも表示される。

$ find . -type f ! -name *.tf

./README.md
./env/prod/user_data/server.sh
./env/prod/task_definition/container.tpl
./env/prod/task_definition/migration.json
./env/prod/task_definition/nginx.tpl

mtime | 5〜10日前になんのファイル作成したっけ、、、

まぁ、厳密には以下の指定の仕方では指定した値を含まず「6 ~ 9の間で検索」ということにはなるのですが、一旦わかりやすさベースで...

$ find . -type f -mtime +5 -mtime -10

./module/network/outputs.tf
./module/network/main.tf
./module/network/variables.tf
./module/alb/outputs.tf

...

./env/dev/variables.tf
./env/stg/outputs.tf
./env/stg/main.tf
./env/stg/variables.tf

size | ディスク異常に圧迫してるんだけど...

-size
    k kilobytes (1024 bytes)
    M megabytes (1024 kilobytes)
    G gigabytes (1024 megabytes)
    T terabytes (1024 gigabytes)
    P petabytes (1024 terabytes)

$ find . -size +10M

./module/route53/big_file2.txt
./env/big_file1.txt

ん?なんだこれは...

$ ls -lh ./module/route53/big_file2.txt
-rw-------  1 user  staff   250M  2  6 15:27 ./module/route53/big_file2.txt

$ ls -lh ./env/big_file1.txt
-rw-------  1 user  staff   500M  2  6 15:27 ./env/big_file1.txt

500MB!? なんだこれは!!!!!!

みたいなこともできます。

ついでに以下のように範囲で指定することもできます。

# 200MB ~ 300MBで検索
$ find . -size +200M -size -300M

./module/route53/big_file2.txt

あれ、30分前に何のファイル作成したっけ?

$ find . -type f -mmin -30

./module/route53/big_file2.txt
./env/big_file1.txt

はい、すいません、例の巨大ファイルは自分が作成しました。。。
みたいなことも出来ます。

最後に

findコマンド、便利ですね。
このコマンドは覚えておくと調査する時にかなり役立ち、これが他のエンジニアとの調査力の差に繋がると思っています。さらにShellScriptと一緒に用いれば物凄い威力が発揮される。ただし、ShellScriptを使ってツールを作るとなると容易にブラックボックスなコードになりえるのでオススメはしません(と言いつつ自分はShellScriptで「定期的に2ヶ月前のログを削除する処理」を実装してしまいましたが...logrotateコマンドというものがあるのですがそれでは要件みたせなかったの...)

全然関係ないけど早くGoやらないとなぁ、、、

Discussion