高度なfindコマンドを使いこなす

皆さんfindコマンドは使いますか? なれないうちはtreeをパイプしてlessにつなげて、、などしながらファイルを探しますが(その方が見つけやすい場合もあるけど)、findってちょっと使いづらいという気がしていましたが、使ってみるとなかなか便利! そんなfindをご紹介したいと思います。

高度findとの出会いのきっかけ

findコマンドを使いやすいと感じたのはコマンドの条件指定を複雑にできると知ってからでした。

私の場合「あるディレクトリの下の画像(jpg, jpeg, gif, png, ico)ファイルをみつけたい」というものでした。findを4回実行するのもよいけれど、ちょっと回数多いなぁ、と感じて使い方を調べました。

脱find初心者の手順

まずは書式を覚えましょう。脱find初心者と位置づけるならば覚えることはとてもシンプルです。

コマンド書式のパスと条件を覚える

find [捜査パス] [捜査条件]

コレです。むしろこれだけ(笑)

捜査パスにはファイルを探す対象となるパスを書きます。ファイルシステム全体をファイルを探す対象とするならば「/」でしょうし、今自分のいるディレクトリ配下であるならば「.」と書きます。特定のディレクトリ(例えば、example/というディレクトリ)ならば「./example」または「example」と書きます。これで捜査パスの指定はOKです。

捜査条件には条件を書きます。例えば「*.jpg」というファイル名だとかです。これだけわかっていても十分ですが、何回層までディレクトリを下るのか?とか、最終更新が何分前までだとか、いろいろと条件を指定していきます。

これらの条件を指定して実行すれば、期待のファイルが得られるというわけです。簡単でしょ。では、ちょっと複雑な条件の指定を見てみます。

条件の「且つ(and)」と「もしくは(or)」

これがわかった時に「脱find初心者したなぁ」と感じました(笑)

前に書いた例で説明すると、「jpg」と「jpeg」と「gif」と「png」と「ico」が拡張子のファイルを全て見つけたい!みたいなことです。

jpg拡張子  -name "*.jpg"
jpge拡張子 -name "*.jpeg"
gif拡張子 -name "*.gif"
png拡張子 -name "*.png"
ico拡張子 -name "*.ico"

これらそれぞれを書いてみるとこのようになります。そして、これらを「もしくは(or)」で繋げると条件の完成です。orは「-o」と書きます。ハイフン小文字オーです。

-name "*.jpg" -o -name "*.jpeg" -o -name "*.gif" -o -name "*.png" -o -name "*.ico"

これで検索条件の準備OKです。パスと組み合わせて好きな条件のファイルを見つけられます。

findコマンド参考

find . -name ".jpg" -o -name "*.png"
カレントディレクトリ以下のjpgファイルとpngファイルを表示
find wp-content/uploads -name ".jpg" -o -name "*.png"
wp-content/uploads内のjpgとpngを検索

ちょっとした小技(-exec)

ここまででもちょっとした脱初心者気分ですが、-execを使えるとパイプxargsとかを使わずにすむので更に上級気分です(笑)

-execはみつかった対象ファイルに対してコマンドを実行します。例えば、見つかったファイル全てに対してfileコマンドを実行して属性調べたりなどです。後は、削除したりもできます。

find . -name "*.png" -o -name "*.ico" -exec rm -f {} \;
カレントディレクトリ配下のpngとicoファイルを強制削除

こんな感じです。-execの後の「{}」はみつかったファイル名を意味します。そして最後におまじない的に「\;」をつければOKです。

これで皆さんも脱findしてください!

検索条件が複数の場合のアイデア (2019.1.5追記)

find wp-content/uploads -name "*.php" -o -name "*.ico" -exec rm -f {} \;

久々にfindを使おうと思ってみたら動きませんでした。今までは動いていたのに何故!?(←これも思い込みか、、) と思いながらも調べて見ました。

結論から言うと、findの検索条件が複数になった場合にはエスケープしたカッコ()でくくらないとexecは動作しないみたいです。正しくは下記のような感じです。

find wp-content/uploads \( -name "*.php" -o -name "*.ico" \) -exec rm -f {} \;

条件が一つだったらカッコなしでも効果はあると思うのですが、この場合には2つの条件を書いていたので動いていないようでした。2つ以上の検索条件がつくと区切りがわからなくなるのでしょうかね。

けっこう探したのですがこのカッコで囲む方法にたどり着くまでに時間がかかってしまったので誰かの役に立てればいいなぁ。と思ってます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です