findコマンドで除外したかったので検証

# はじめに
こんにちは！
普段、よくお世話になっている`find`コマンド。

必ずと言っていいほど、一部のディレクトリやファイルを除外したくなります。

除外する方法は幾つかあるのですが、結局どれが一番効率いいのか分からなかったので、検証してみました。

# 検証方法
以下の方法で、特定のディレクトリおよびファイルを除外する
- `find`の`prune`オプション
- `find`の`-not` と `-path` オプション
- `find`の結果を`grep`してから`grep -v`
- `find`の結果を`grep -v`してから`grep`

# 今回の対象プロジェクト
今回は、作りかけのプロジェクトを使います。
```bash
.
├── README.md
├── all.txt
├── node_modules
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   ├── logo512.png
│   ├── manifest.json
│   └── robots.txt
├── src
│   ├── App.css
│   ├── App.jsx
│   ├── App.test.js
│   ├── components
│   │   ├── AddTaskForm.jsx
│   │   ├── CommentForm.jsx
│   │   ├── CommentList.jsx
│   │   ├── Dashboard.jsx
│   │   ├── Header.jsx
│   │   ├── TaskDetail.jsx
│   │   └── TaskPanel.jsx
│   ├── index.css
│   ├── index.js
│   ├── logo.svg
│   ├── reportWebVitals.js
│   ├── setupTests.js
│   └── utils
│       └── api.js
└── tailwind.config.js
```
ここから、node_modulesディレクトリを除いて、`.js` `.jsx` `.css`だけを抽出します。

# 検証開始
時間を計測するため、先頭に`time`を付けてます。
### find -prune -o -print
```bash
$ time find . -name "node_modules" -prune -o \( -name "*.js" -o -name "*.jsx" -o -name "*.css" \) -print
./tailwind.config.js
./postcss.config.js
./src/reportWebVitals.js
./src/App.css
./src/index.js
./src/utils/api.js
./src/index.css
./src/components/Header.jsx
./src/components/CommentList.jsx
./src/components/TaskPanel.jsx
./src/components/AddTaskForm.jsx
./src/components/Dashboard.jsx
./src/components/TaskDetail.jsx
./src/components/CommentForm.jsx
./src/App.test.js
./src/App.jsx
./src/setupTests.js

real	0m0.009s
user	0m0.002s
sys	    0m0.006s
```

### find -not -path
```bash
$ time find . -not -path "**/node_modules/**" \( -name "*.js" -o -name "*.jsx" -o -name "*.css" \)
./tailwind.config.js
./postcss.config.js
./src/reportWebVitals.js
./src/App.css
./src/index.js
./src/utils/api.js
./src/index.css
./src/components/Header.jsx
./src/components/CommentList.jsx
./src/components/TaskPanel.jsx
./src/components/AddTaskForm.jsx
./src/components/Dashboard.jsx
./src/components/TaskDetail.jsx
./src/components/CommentForm.jsx
./src/App.test.js
./src/App.jsx
./src/setupTests.js

real	0m1.651s
user	0m0.088s
sys	    0m1.309s
```

### find + grep -v + grep -e
```bash
$ time find . -type f | grep -v "node_modules" | grep -E "\.(js|jsx|css)$"
./tailwind.config.js
./postcss.config.js
./src/reportWebVitals.js
./src/App.css
./src/index.js
./src/utils/api.js
./src/index.css
./src/components/Header.jsx
./src/components/CommentList.jsx
./src/components/TaskPanel.jsx
./src/components/AddTaskForm.jsx
./src/components/Dashboard.jsx
./src/components/TaskDetail.jsx
./src/components/CommentForm.jsx
./src/App.test.js
./src/App.jsx
./src/setupTests.js

real	0m1.685s
user	0m0.128s
sys	0m1.359s

```

### find + grep -e + grep -v
```bash
$ time find . -type f | grep -E "\.(js|jsx|css)$" | grep -v "node_modules"
./tailwind.config.js
./postcss.config.js
./src/reportWebVitals.js
./src/App.css
./src/index.js
./src/utils/api.js
./src/index.css
./src/components/Header.jsx
./src/components/CommentList.jsx
./src/components/TaskPanel.jsx
./src/components/AddTaskForm.jsx
./src/components/Dashboard.jsx
./src/components/TaskDetail.jsx
./src/components/CommentForm.jsx
./src/App.test.js
./src/App.jsx
./src/setupTests.js

real	0m1.702s
user	0m0.217s
sys	0m1.368s
```


## 各コマンドの実行時間比較結果

| コマンド                                       | 実行時間 (秒) | 備考 |
|:---------------------------------------------|:----------:|------|
| `find -prune -o -print`                  | 0.009     | 最速 |
| `find -not -path`                        | 1.651     | 遅い |
| `find + grep -v + grep -e`               | 1.685     | 遅い |
| `find + grep -e + grep -v`               | 1.702     | 遅い |

**考察**

今回の検証結果から、`find -prune -o -print` の組み合わせが最も高速に処理できることが分かりました。 
これは、`-prune` オプションが "node_modules" ディレクトリを探索対象から完全に除外するため、find コマンド自体が不要なディレクトリを走査する必要がなくなり、処理速度が向上するためと考えられます。

一方、`find -not -path` や `grep` を利用した方法は、`find` コマンドが全てのファイルとディレクトリを走査した後に、`-not -path` や `grep` でフィルタリングを行うため、処理に時間がかかってしまうと考えられます。 
特に、`node_modules` ディレクトリはファイル数やディレクトリ数が非常に多いため、これらの方法では処理時間の差が顕著に現れたのでしょう。

# 結論

"node_modules" のようにファイル数やディレクトリ数が非常に多いディレクトリを除外する場合は、`find -prune -o -print` を利用するのが最も効率的です。

# さいごに
さて、いかがだったでしょうか。
今回は、findコマンドにおける除外に関して検証しました。

やり方は他にもあると思うので、改めて追記しようと思います。

みなさんも、効率の良いコマンドで作業時間を短縮しましょう！