2007年03月30日 00:15 [Edit]

勝手に添削 - find(1)

まずはこちら。

$ find . -type f | fgrep index.html

これは

% find . -type f -name index.html

でOK。パイプ不要。.htmlだけ見つけたい時も

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

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

$ find . -name '*~'

と同じなのだが、なんで上記の例でfgrepを使っているか不明。

ここからが本番。

$ find . -name '*~' -exec rm {} \;

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

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

か、

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

がいいだろう。-type fをつけることで、ファイルのみを検索対象にしている。

これらのうち、一番のお薦めは後者。-execxargsも、rmを何度も実行するが、perlにパイプする例では、findperlしか実行されないので高速かつ負荷が低い。

実はベストなのは

% find . -type f -name '*~' -delete

だったりするが、-deletefindによってはサポートしていなかったりするので(BSDのfindはサポートしている)、perlにパイプする技を覚えておいても損はない。

$ find . -name .svn -type d -exec rm -rf {} \;

これも

% find . -name .svn -type d | perl -MFile::Path -nle "rmtree $_"

でOK。

% find -uid 0

-uidは多分GNUのfindでしかサポートされていない。POSIX標準は

% find . -user root

または

% find . -user 0

ちなみに条件を反転させるには、

% find . \! -user dankogai

とすればいい。

$ find -uid 0 -exec chown jokagi {} \;

これは

% find . -user root | xargs chown jokagi

がいいだろう。perlでも出来ないことはないが、perlのchownはUID指定しかできない上、GIDも指定しなければならないので、互換性を持たせて書こうとすると

% find . -user root | perl -nle 'BEGIN{$u=(getpwnam("jokagi"))[2]};@s=lstat($_);chown $u,$s[5], $_'

とあまりに長くなっていまう。

何はともあれ、find(1)は何かとよく使う割にやたらとオプションがあるコマンドなので、迷ったらすぐにman findするのが肝要なのだけど、用例がないといまいちピンと来ないので、用例集が一つ欲しいところ。そういうわけで「私はfind(1)をこう利用してます。というのがあったら、本entryへのTBないしcommentして欲しい。

理想を言えば、manwikiとかが欲しいかも。

Dan the find(1)er

See Also:

この記事へのトラックバックURL

この記事へのトラックバック
404 Blog Not Found:勝手に添削 - find(1)
404 Blog Not Found:勝手に添削 - find(1)【】at 2012年01月21日 10:38
find(1)ねたというのは、定期的にblogosphereを賑わせるものだし、それはそれでよいし、私自身いくつか書いているのだけど.... findを極める! - IDEA*IDEA 〜 百式管理人のライフハックブログ 〜 タグ「find」を含む新着エントリー - はてなブックマーク 404 Blog Not ...
findを極めたかったら、statを抑えよ【404 Blog Not Found】at 2009年05月13日 13:35
これ、以前にも書いたのですがここでおさらい。 subtech - PBD - 1ディレクトリにン千万ファイルあるときの削除方法どうやるのが一番良いんだろ。
tips - 1ディレクトリにファイル大杉の場合の削除法【404 Blog Not Found】at 2007年09月20日 13:43
[404 Blog Not Found:勝手に添削 - find(1)] find の話題が盛り上がっているようだが、「last-modified が30日以上前のファイルを特定ディレクトリに退避」なんて処理にはよく find を使う。特に spam や virus 等、一時保存してその後は破棄するようなデータには cron で仕...
find 道は凄腕システム管理者への近道【World Wide Walker】at 2007年04月02日 20:46
findの中でも有用なのだが使いにくいものに -perm オプションがある。fileの permissionを条件にするものだ。 という書き出しにしてみたが、そんなに permオプション使うかな、正直なところ。このまえ、自分が読めないファイルを見つけるために find . ! -perm +044 とかや
find の -permを使う tips【ダイミテイ】at 2007年03月31日 17:01
-execもxargsも、rmを何度も実行するが、perlにパイプする例では、findとperlしか実行されないので高速かつ負荷が低い。 404 Blog Not Found:勝手に添削 - find(1) コメントでも指摘されてるけど、確かrmが何度も実行されるのはオプションをつけた時だよなぁ、とちょっと気
[技術]xargsのオプションって環境によるのね【nak2kのメモ帳】at 2007年03月30日 10:20
dankogaiさんのblogでいろいろと書かれていて参考になったというかほぼその通りだと思ったのだけど、いくつか違和感が。 .htmlだけ見つけたい時も % find . -type f -name \*.html でOK。findはシェルのワイルドカードを受け付ける。ただしシェルにそれを展開して欲
[tips]findの用法あれこれ【18 til i die】at 2007年03月30日 10:06
ディレクトリ名に0x20(空白)が入るMac OS X環境でfindに-print0を使わずにxargsで受け取るのはヤバい。かなり危険。一度AppleがiTunesのアップデートスクリプトで0x20デリミタの想定外動作をやらかして、誤消去したことがあったよなぁ。なので「findには必ず-print0オプシ...
いまどきfindとxargsを使う時は-print0と-0を忘れずに【void GraphicWizardsLair( void ); //】at 2007年03月30日 06:34
ウノウラボ Unoh Labs: コマンドラインで作業する上で知っておくといいテクニック% find . -name '*~' -exec rm {} ; 404 Blog Not Found:勝手に添削 - find(1)% find . -type f -name '*~' | xargs rm % find . -type
find には sh!【無精で短気で傲慢なプログラマ】at 2007年03月30日 02:36
お、タイムリーな話題だったので。 404 Blog Not Found:勝手に添...
findコマンド。【Junnama Online (Mirror)】at 2007年03月30日 02:06
まずはこちら。 $ find . -type f | fgrep index.html (snip) $ find . -name ’*~’ と同じなのだが、なんで上記の例でfgrepを使っているか不明。 404 Blog Not Found:勝手に添削 - find(1) あっはっはっは. 不明といわれても仕方がないですね.仰るとおりです(痛 普段fin...
[dankogai][odz] また添削してくれた!!【よくきたはてダ】at 2007年03月30日 01:39
この記事へのコメント
> -d $'\0'

$ echo -n $'\1' | od -t x1
0000000 01
0000001

$ echo -n $'\0' | od -t x1
0000000

てことは、-d '' でイーンジャネーノ?
Posted by kk at 2007年03月31日 02:58
いつも xargs つかわないで、
find . -type f -print0 | while read -r -d $'\0' f;do cmd1 "$f" ; cmd2 "$f"; done
とかやってます。
Posted by ななし at 2007年03月30日 14:59
xargs(1)はコマンドライン長の上限までは一度に渡すので、今時のOSならそうそう何度もは起動されない。

| perl -ne unlink は、いたずらか何かのミスで \n 入りのファイルが置かれていたら危険。

| xargs rm に至ってはスペースの入ったファイルがあるだけでダメ。

今時、 find dir -print0 | xargs -0 cmd は常識だよなあ。POSIXにはないけど、どうせみんなGNUか*BSDでしょ。
Posted by 774 at 2007年03月30日 10:44
rmの用例ですが、-execは何度もrmを実行しますが、xargsは条件を満たすファイルを一度に消してくれたと思います。が、環境依存があるのかも?
手元の環境(FedoraCore3)では一度に消してくれるようです。
Posted by ssilver at 2007年03月30日 01:23
用例と言うわけでは無いですが、
find の -print0 と xargs の -0 オプションはよく使います。
双方を併用する事でセパレーターに改行ではなく NUL 文字を使うので安全性が増すはずです。
Posted by b-wind at 2007年03月30日 00:45