はじめに
こんにちは!
普段、よくお世話になっているfind
コマンド。
必ずと言っていいほど、一部のディレクトリやファイルを除外したくなります。
除外する方法は幾つかあるのですが、結局どれが一番効率いいのか分からなかったので、検証してみました。
検証方法
以下の方法で、特定のディレクトリおよびファイルを除外する
-
find
のprune
オプション -
find
の-not
と-path
オプション -
find
の結果をgrep
してからgrep -v
-
find
の結果をgrep -v
してからgrep
今回の対象プロジェクト
今回は、作りかけのプロジェクトを使います。
.
├── 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
$ 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
$ 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
$ 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
$ 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コマンドにおける除外に関して検証しました。
やり方は他にもあると思うので、改めて追記しようと思います。
みなさんも、効率の良いコマンドで作業時間を短縮しましょう!