Pocket

Linuxで作業をしていると、ファイル名やテキストファイル内の文字列がどのファイルに書き込まれているか調べたり、階層のリストやファイルリストをテキストファイルに出力したりすることがあると思います。

また、ディレクトリの階層が深くなって作成したファイルをどこに保存したかわからなくなってしまった・・・という経験がある方も多いのではないでしょうか?

今回は、そんな時に役立つ find というコマンドについて、ご紹介します。

文字列検索に便利なfindコマンド

findは、ファイルやディレクトリを検索するときに使うコマンドです。
findは、検索条件に合致するファイルの一覧を表示するだけでなく、見つかったファイルに対して「-exec」オプションを使って別のコマンドを実行するといった活用法があります。

基本的な使い方
find [オプション] 検索したいディレクトリ 検索条件

よく使うオプション

-type ファイルのタイプを指定するオプションです。ディレクトリを示す「d」や通常のファイルを示す「f」がよく使われます。
-name 検索対象としたい文字列を指定します。
-exec 条件に合致したファイルに対して「-exec」の後に指定したコマンドを実行できます。
-path 指定した文字列を元にヒットしたファイルのパスを検索します

たまに使うオプション

-atime n
-ctime n
-mtime n
n日前にアクセスされたファイルを見つけます。
n日前にステータス情報が変更されたファイルを見つけます。
n日前に修正されたファイルを見つけます。
※ いずれも、-n +n ではn日より前後の指定ができます。
-group
-user
指定したグループのファイルを見つけます。
指定したオーナのファイルを見つけます。
-perm 指定したパーミッションのファイルを見つけます。

例えば、/var/www/htdocs/wordpress 以下の名前が「upload*」に合致するディレクトリを検索したい場合のコマンドは以下です。

find /var/www/htdocs/wordpress -name "upload*" -type d

検索文字列には「*(半角のアスタリスク)」ワイルドカードが使えるので、「upload-dir」など、uploadという文字列を含むディレクトリを検索することができます。
文字列の完全一致で検索をする場合、「*(半角のアスタリスク)」は不要です。

上記コマンドは、/var/www/htdocs/wordpress から、名前が upload を含むディレクトリを検索しなさいね。という意味になります。

また、A OR B というように、複数条件で検索することができ、その場合は、-o -name で複数条件にマッチした検索をすることもできます。
以下の例は、.jpg と .gif を、-o オプションを使って、すべて検索する場合のコマンドです。

find ./ -name "*.jpg" -o -name "*.gif" -type f

-execオプションで検索結果から別のコマンドを実行する

findコマンドを使っていて素晴らしいと感じるのは、この -exec オプションによって、-exec 以降に指定したコマンドが実行できるところだと思います。

例えば、Macで作業をしている方が ftp などでフォルダをアップロードすると、.DS_Store や .AppleDouble といった隠しファイルが同時にアップされることがありますが、このようなファイルはサーバーには必要ないファイルなので、コマンドで一括削除したい・・・と感じることがあります。
そうようなときに役立つのが -exec オプション を使った、検索結果から該当するファイルを一括削除するコマンドです。

Linuxでファイルを削除ときには、rm というコマンドを使いますが、-exec オプションに rm をつけることで、find でヒットしたファイルを、順次 rm コマンドで削除していくことができます。

find ./ -name ".AppleDouble" -o -name ".DS_Store" -type f -exec rm {} \;

\; までの文字列が、コマンドとして認識され、{} には find でヒットしたファイル名やディレクトリ名に置き換えられていきます。

-exec オプションを使うときの注意点
※ -exec を使う場合、条件式に誤りがあると予期しない結果を招く恐れがあるので、必ず一度は -exec なしで実行して検索結果が期待するものであることを確認しましょう。特に rm などのファイルを削除するコマンドを使う場合、消してはいけないファイルを消してしまったりすると大変です。

↓ 一度 -exec なしで検索結果を確認しましょう!
20160220

また、特定の単語が含まれるファイルを検索する場合には、-exec オプションに grep -l をつけます。
grep は、特定の単語をソースコードから検索するときに Linux でよく使われるコマンドで、find の -exec オプションに grep を使うことで、検索対象のソースコードから単語を検索し、該当するファイルを表示することができます。

以下のコマンドは、.(ドット)を含むファイルから、common.css が記述されているファイルを表示するコマンドです。

find ./ -name "*.*" -exec grep -l "common.css" {} \;

なお -exec は、検索結果から1ファイル毎に rm が行われるため、find の検索結果が大量にある場合には、処理に時間がかかることがあります。
その場合は -exec を使わず、 findに xargs というコマンドをパイプ( | )で繋ぐことで、効率的に処理をすることができます。

find ./ -name ".AppleDouble" -o -name ".DS_Store" -type f | xargs rm

検索結果をテキストファイルに書き出してみる

find はファイルやディレクトリ、ファイル内の国定の文字列を検索したいときに便利なコマンドですが、その結果を資料としてログに出力しておきたいときなどに使える「リダイレクション」についても、ご紹介をしておきたいと思います。

書き出す方法は簡単で、実行するコマンドに対して > の後に書き出すファイル名を指定します。

find [オプション] 検索したいディレクトリ 検索条件 > ファイル名 

リダイレクション( > )は、Linuxでファイルを書き出す時によく使う方法で、コマンドの結果を画面に表示するのではなく、ファイルに書き出すときに利用します。

以下の例は、カレントディレクトリ配下のドット(.)を含むファイルから「common.css」が記述されている全ての検索結果を result.txt に書き出すときのコマンドです。

find ./ -name "*.*" -exec grep -l "common.css" {} \; > result.txt

.phpのファイルリストを作る時などは、以下のようにします。

find ./ -name "*.php" > result.txt

まとめ

いかがでしたか? find は単純なファイル検索から高度な検索まで、Linuxのコマンドを組み合わせることで、高度な検索をおこなうことができる素晴らしいコマンドです。find を知っておくと、大量のファイルから素早く目的のファイルを探し当てることができるので、探す手間や時間を大幅にカットできますよ!

 

スタッフ募集のお知らせ

株式会社それからデザインでは現在、エンジニア・プログラマー、デザイナー、ディレクターを募集しています。自社サービスやクライアント企業のブランディングに関わるモノづくりの現場であなたの経験を活かしてみませんか?
ご興味のある方は、下記より募集要項をご覧ください。

生きるように働く人の仕事探しサイト「日本仕事百貨」に、当社のSE・プログラマー募集の記事が掲載されました。是非ご覧ください。