旧それなりブログの跡地、画像やスタイルやJSなどが壊れてることがあります。

findコマンドの論理演算子を復習

2011年6月19日

findコマンドは、-type f や -name ‘hoge’ などの様々な条件を使うことが出来ますが
加えて AND や OR や NOT の論理演算子も使うことができます

今までテキトーに使ってたので復習しました

AND文

AND文は評価式を -and または -a で結合します

まず、動作確認用に以下のようにファイルを配置します

$ tree
.
|-- dark-chaos
|-- dark-neutral
|-- dark-row
|-- light-chaos
|-- light-neutral
|-- light-row
|-- neutral-chaos
|-- neutral-neutral
`-- neutral-row

動作確認してみましょう

$ find . -name '*light*' -and -name '*row*'
./light-row

ファイル名に ‘light’ が含まれており、かつ、’row’ が含まれている ‘lignt-row’ ファイルがヒットしました

書式は以下のように

$ find <検索基底ディレクトリパス> <評価式1> <論理演算子1> <評価式2> [<論理演算子2> <評価式3> ... ]

いわゆるプログラミング言語のif文と同じような書き方です

ただし

$find . -name '*light*' -name '*row*'
./light-row

上記のように、ANDの場合は論理演算子を省略して書くことも出来ます
ググって出てくるサンプルなどは大抵こちらの記法で書いてあるので注意が必要です

OR文

OR文は -or または -o で評価式を結合します

$find . -name '*light*' -or -name '*row*'
./dark-row
./light-row
./neutral-row
./light-chaos

‘lignt’ または ‘row’ を含むファイルがヒットします

NOT文

NOT文は -not または ! (半角エクスクラメーション) を評価式の前に挿入します

$find . -not -name '*light*'
.
./neutral-chaos
./dark-row
./dark-chaos
./neutral-neutral
./neutral-row
./dark-neutral

‘light’ を含まないファイルがヒットします

細かい動作確認

NOT文をつなげる場合を一応書いてみます
まぁ「評価式の前に置く」という基本ルール通りでした

$find . -name '*row*' -and -not -name '*neutral*'
./dark-row
./light-row

今度は、ANDとORの優先順位の確認をしてみます

$find . -name '*light*' -or -name '*dark*' -and -name '*neutral*'
./light-row
./light-neutral
./light-chaos
./dark-neutral

‘a OR b AND c’ と OR を AND の前に書きましたが、
ちゃんとAND文が優先されて ‘a OR (b AND c)’ という評価順序になっています

.svnを除くディレクトリ全てを権限変更するサンプル

ということで、実践編
.svnディレクトリ以外の権限を変更するコマンドです

$ find /path/to/dir -type d -and -not -path '*.svn*' | xargs chmod 0777

※評価式 -type d は、ディレクトリのみをマッチします
※評価式 -path ‘*.svn*’ は、’.svn’ 文字列を含むパスを持つファイルのみをマッチします
 なお、-name の場合はファイル*名*のみ検索対象にします

‘*’ はzshの補完のそれと違う意味

find の場合は ‘*abc*’ は「’abc’ が含まれていること」を意味します
zsh の補完は ‘*abc*’ は「’abc’ とその前後に1文字以上の何かが含まれていること」を意味します
例えば、zshで

$ ls row*

で先のディレクトリを補完しても何もでませんが、以下なら出ます

$ls *row
dark-row  light-row  neutral-row

これは * が「1文字以上」を意味するもので「0文字以上」ではないためです

参考リンク

UNIXの部屋 コマンド検索: find ファイルを検索する。
http://x68000.q-e-d.net/~68user/unix/pickup?find

指定DIR以下の’.svn’以下を全部削除するコマンド
http://kjirou.sakura.ne.jp/mt/2008/01/dirsvn.html