findの用法あれこれ

dankogaiさんのblogでいろいろと書かれていて参考になったというかほぼその通りだと思ったのだけど、いくつか違和感が。

.htmlだけ見つけたい時も

% find . -type f -name \*.html

でOK。findはシェルのワイルドカードを受け付ける。ただしシェルにそれを展開して欲しくないので、\でエスケープしている。

findとか、他のコマンドにシェルのワイルドカードを渡したいときは何も考えず機械的にシングルクォートで

% find . -type f -name '*.html'

と書くようにしているのだが、どうなんでしょうか。確かにスラッシュ1つの方がタイプ数は少ないが、.htmも含めてバックアップファイルだけ探そうと思って

% find . -type f -name \*.htm\?.\*

とかするともう見ただけで発狂しそうになるのは私だけ?(w
あと、otsuneさん

ディレクトリ名に0x20(空白)が入るMac OS X環境でfindに-print0を使わずにxargsで受け取るのはヤバい。かなり危険。一度AppleiTunesのアップデートスクリプトで0x20デリミタの想定外動作をやらかして、誤消去したことがあったよなぁ。
なので「findには必ず-print0オプションを付けて、xargs -0で受け取る」というのを広く世に広めたい。例えば

find . -type f -print0 -name '*~'  | xargs -0 rm 

という感じ。

はなるほどと思った。私も意識して世に広めようと思う。
ちなみにワタシがよく使うのは、やはりなんと言っても

% find . -type f | xargs rm

で、~/rpmディレクトリを掃除するのに多用する。いちいちSPECSとSOURCESに降りて消すのはめんどくさいよ。とパッケージャらしい愚痴をこぼしてみる。でもこれも、ちゃんと-print0と-0を付けて

% find . -type f -print0 | xargs -0 rm

とか叩くようにしよう。そうしよう。

Perlへパイプするとわ…

この-exec、かつては有用だったがxargsやperlがある昨今ではあまり使わない。

% find . -type f -name '*~' | xargs rm

か、

% find . -type f -name '*~' | perl -nle unlink

がいいだろう。-type fをつけることで、ファイルのみを検索対象にしている。
これらのうち、一番のお薦めは後者。-execもxargsも、rmを何度も実行するが、perlにパイプする例では、findとperlしか実行されないので高速かつ負荷が低い。

いや、Perlへパイプする人はあまりいないんじゃないかと…Linuxとかだと、rmもsyncのタイミングでしか実行されないし、xargsも「command(デフォルトは/bin/echo) に文字列群を続けたコマンドラインを実行する」から、そんなに負荷はないんじゃないかな。試してないから確信はないけど。