2011年2月6日

findコマンドの-pruneオプションのススメ

主にLinuxなどのUnix機でファイルを検索するためのfindコマンドですが、検索する場所や条件によっては大量にヒットしてしまい困る時があります。

そんな時は不要なファイルやディレクトリを!否定演算子で指定したり、-pathオプションを使用したりすればいいのですが、Solarisや古いバージョンのLinuxでは使えないことがあるようです。

そこで登場するのが-pruneオプションで、これはその前に指定された条件に合致するディレクトリを降りずに検索しないようになります。
$ find .
.
./aaa
./aaa/bbb
./aaa/bbb/111.txt
./nnn
./nnn/mmm
./nnn/mmm/222.txt
./xxx
./xxx/yyy
./xxx/yyy/333.txt
例えば、上記の様なディレクトリ/ファイル構成からmmmディレクトリ以下をヒットしないようにする場合は下記のオプションを指定します。
$ find . -name mmm -prune -o -print
.
./aaa
./aaa/bbb
./aaa/bbb/111.txt
./nnn
./xxx
./xxx/yyy
./xxx/yyy/333.txt
ちなみに!否定演算子と-pathオプションを使った場合は下記の通りです。
$ find . ! -path *mmm*
.
./aaa
./aaa/bbb
./aaa/bbb/111.txt
./nnn
./xxx
./xxx/yyy
./xxx/yyy/333.txt
-oオプションは、左の条件が真なら右の条件を実行するOR演算子的なオプションで、-printオプションは条件に合致したディレクトリ/ファイル一覧を出力(print)するオプションです。-printオプションは未指定の場合の動作と同じですが、-pruneオプションを使う場合は-oオプションとともに明示的に指定する必要があります。
(情報を表示する-lsオプションでも可)

これを応用すれば、ファイルが大量にあるログディレクトリのファイル郡を除外してfindコマンドを実行したりする事ができます。また、上記例ではディレクトリもヒットしていますが、-type fオプションでファイルのみヒットさせたり、複数の-nameオプションを括弧でくくる事で複数条件に対応させる事もできます。
(ただし、括弧でくくる場合は\記号でエスケープする必要があります)
$ find . -name mmm -prune -o -type f -print
./aaa/bbb/111.txt
./xxx/yyy/333.txt
$ find . \( -name bbb -o -name yyy \) -prune -o -type f -print
./nnn/mmm/222.txt
findコマンドを多用するきっかけとなった以下の記事やfindコマンドマニュアルも合わせて読めば、よりfindコマンドの奥深さを知る事ができるかと思います。