- blogs:
- cles::blog

find で特定のディレクトリを除外してファイルを検索する

find で特定の名前のディレクトリ(例えば .svn とか)を除外してファイル検索をしたい場合には -prune を使えばいいというのは分かっているのですが、使い方を覚えていなくて毎回 man*1 と格闘する羽目になるのでメモ。
たとえば /path/to/dir 以下の .svn 以外のフォルダの中の hoge を含むファイルを検索する場合は以下のような感じ。
ポイントは -prune と -print の位置です。この条件式は括弧をつけてわかりやすくすると以下のようになります。
-o は論理演算の OR を表しますが、一般的なプログラミング言語と同様に短絡評価されます。例えば、ORの左辺が T だった場合、右辺を評価するまでもなく答えが T であることがわかるため、その時点で右辺の評価(実行)は行われません。これについては OR の真理値表を見れば明らかです。AND についてもどうように左辺が F の場合は右辺の評価はしませんというのが、短絡評価です。
上記の式の括弧内は AND 演算となるので、 -type d -name '.svn' -prune は -type d -and -name '.svn' -and -prune となり、-type f -name '*hoge*' -print は -type f -and -name '*hoge*' -and -print となります。 この二つの式が OR で繋がっているので、右側が評価される(つまり結果が表示される可能性がある)のは、左側が F の場合だけです。つまり最初の式が T と評価された場合は(後の式は評価されないので)そのファイル名は表示されません。
さらにこれに -prune の「真を返す。ファイルがディレクトリの場合は、そのディレクトリ以下に 降りて行かない。」という意味が加わりますので、左側が T と評価されたディレクトリの下は検索対象ではなくなります。つまり、.svn ディレクトリ以下のファイルが検索対象外になるということです。
ちなみに右側の式の -print は省略できません。これは「式の中に -prune 以外のアクションが存在しない場合は、 式の結果が真になったすべてのファイルに対して -print が実行される 」と定義されているためで、右側の -print を省略してしまうと、-prune を実行したときにも -print が表示されるようになってしまうためです。つまり、以下のように書いたのと同じになってしまうということです。ほとんどの場合、これは望んだ結果が得られないはずです。
このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/7528
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
コメントは承認後の表示となります。
OpenIDでログインすると、即時に公開されます。
OpenID を使ってログインすることができます。
2 . 年次の人間ドックへ(94878)
3 . 福岡銀がデマの投稿者への刑事告訴を検討中(94797)
4 . 三菱鉛筆がラミーを買収(94480)
5 . 2023 年分の確定申告完了!(1つめ)(94456)