それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

find で指定のフォルダを除外するには

find コマンド結果多すぎて除外したいフォルダがありませんか?

find で除外したものといえば、.git や ruby だったら bundle/vendor など、find の結果から除外するには

find の -not オプションを使います

find は「検索条件」を列挙するタイプのコマンドなので、検索条件に -not をつけて否定形にすればいいわけです。

find . -not -iwholename '除外したい名前'
.git を無視する例。

一番使いそうなのがこれ。.git

find . -not -iwholename '*/.git/*'

-name と -iwholename とは?

find のオプションで、 -name と -iwholename は少し違う

  • -name : 自身のファイル名にマッチ
  • -wholename : 自身のファイルのパス名にマッチ
  • -iwholename : wholename のCaseInsensitive版

たとえば 、vendor/bundleについて -name / -iwholename でマッチすると

次のような結果になる。

名前 オプション 結果
vendor -name 'vendor' マッチする
vendor/bundle -name 'vendor' ×
vendor -iwholename 'vendor' マッチする
vendor/bundle -iwholename 'vendor' マッチする

のように検索結果のパス名(ディレクトリ名)にマッチさせることが出来る

-not -iwholename の意味

-iwholenameで .git をパス名に持つのをマッチさせて、それを -not で否定形にしている。

理屈がわかれば便利ですね

alias できない困った問題

.git を常に無視したいと思っても、find コマンドの性質上、検索パスは絞込条件の前に設置する必要がある。

find path -検索条件 -検索条件 -検索条件 #出来る
find  -検索条件 -検索条件 -検索条件  path # できない

そのために、alias をつけておくことが出来ない。

alias find="find $@ -not -name ss" # 出来ない

どうしてもやりたければfunctionを書くしか無いです。

function find { $( which find ) "$@"  -not -iwholename '*/.git/*'  ; }

関数書くしか解決策がないけども、function 使うのが手軽でベターな解決方法。

参考資料

http://stackoverflow.com/questions/2314643/how-can-i-get-find-to-ignore-svn-directories