【Linux】find -nameでファイル名で検索する方法
こんにちは。
普段はIT業界についてのブログを執筆してるエンジニアです。
» 参考:プログラマーの年収は200万円以下です【IT業界の残酷な成功法則】
今回は、linuxについての解説記事です。
linuxのfindコマンドでファイル検索したい人
「linuxでfindを使ったファイル検索をしたいです。ファイル名の指定には正規表現も使えますか?どのように書いたら良いかわかりやすく具体的を示してください。」
こんな悩みを解決します。
この記事を書いている私はIT業界歴12年、うちサーバエンジニア歴6年、年収1,000万円ちょっとの金融系エンジニアです。IRIXやSolarisなどのUnixやmac、Linuxなど様々なUNIX系環境を扱ってきました。
これまでの経験を踏まえ、コマンドの解説に留まらず実務視点で利用方法を記事にしました。お役にたちましたら幸いです。
本記事で扱うのはLinux/Macのfindコマンドです
本記事では、LinuxまたはMac環境を前提にしています。MS/DOSのfindコマンドは特定の文字列をファイルから探すもので、Linuxのgrepコマンドに近い振る舞いをします。
本記事の内容
- 1. 【基本的な使い方】find 《ディレクトリ名》 -name 《ファイル名》
- 2. 【使用例1】ファイル名を指定して検索する
- 3. 【使用例2】ファイル名の一部だけ指定して検索する【正規表現】
- 4. タイムスタンプやパーミッション情報も表示する
- 5. find -nameとlsの違い
- 6. 開発・運用業務上の注意点
1.【基本的な使い方】find 《DIR》 -name 《FILE》
ファイル名を指定してfindコマンドを実行し、ファイルを検索するには以下の構文を使います。
-name
《ファイル名》
このとき、検索ディレクトリの下にサブディレクトリがあれば、サブディレクトリも含めて根こそぎファイル検索をかけます。
2. 【使用例1】ファイル名を指定して検索する
以下の例では、findコマンドを実行し、ファイル検索を行う簡単な例です。
% find . -name "file1.txt"
検索ディレクトリの下のfindtest
とfindtest2
という2つのディレクトリに検索対象のfile1.txt
があるとします。実行結果は以下のようになります。
./findtest/file1.txt ./findtest2/file1.txt
3. 【使用例2】ファイル名の一部だけ指定して検索する【正規表現】
正規表現を使用することで、ファイル名の一部だけ指定して検索することができます。
% find . -name "file*.txt"
検索ディレクトリの下のfindtestとfindtest2という2つのディレクトリに検索対象のfile[1〜3].txt
があるとします。実行結果は以下のようになります。
./findtest/file1.txt ./findtest/file2.txt ./findtest/file3.txt ./findtest2/file1.txt ./findtest2/file2.txt ./findtest2/file3.txt
ファイル名の数字を指定して、以下のように記述しても同じ結果を得られます。
% find . -name "file[1-3].txt"
4. findの結果にタイムスタンプやパーミッション情報も表示する
-ls
find -lsオプションの使用例
ls -lを実行した時のように、見つかったファイルの情報を詳細に出すには-lsオプションを使います。
% find . -name "file[1-3].txt" -ls
結果は以下の通りです。
29178829 0 -rw-r--r-- 1 root staff 0 7 25 21:41 ./findtest2/file2.txt 29178831 0 -rw-r--r-- 1 root staff 0 7 25 21:41 ./findtest2/file3.txt 29178827 0 -rw-r--r-- 1 root staff 0 7 25 21:41 ./findtest2/file1.txt 29178727 0 -rw-r--r-- 1 root staff 0 7 25 21:38 ./findtest/file2.txt 29178730 0 -rw-r--r-- 1 root staff 0 7 25 21:38 ./findtest/file3.txt 29178725 0 -rw-r--r-- 1 root staff 0 7 25 21:38 ./findtest/file1.txt
5. find -nameとlsの違い
ファイルを検索する際にlsよりfindを用いるメリットは、サブディレクトリ内の検索もできることです。zshまたはbashの拡張競うでglobstarを用いれば、lsでも前の例と同じ結果を得られます。以下に例を示します。
% ls -l **/file[1-3].txt
findでもlsでも同じ結果が得られますが、うまく機能しないこともあります。
- 検索するファイルの数が少ない場合、どちらを使ってもいい
- 検索するファイルの数が多い場合、find -nameを使う
幾つか理由がありますが、lsの*や**を使った場合は、シェルが*や**を実態のファイルパスに変換してからコマンドが実行されるので、実際は次のように処理されます。
% ls -l ./findtest/file1.txt ./findtest/file2.txt ./findtest/file3.txt ./findtest2/file1.txt ./findtest2/file2.txt ./findtest2/file3.txt
そのため、ファイル数が多いと引数が多すぎてエラーとなってしまうのです。
この他、処理するアルゴリズムや処理の多様さの面でfindの方がずっとリッチです。簡単なファイル操作はls、より複雑・より負荷の高い検索はfind -nameを使うと覚えて置くと良いでしょう。
6. 開発・運用業務上の注意点
上述している通り、対象のファイル数が多いとCPU負荷が高くなりますので、環境を共有している場合には他の人のテストや業務に影響を与えないよう気を付ける必要があります。
特にfindした結果をパイプ(|)で渡してxargsで処理を行う場合には要注意です。仮にfindの結果見つかったファイルが1,000あれば、xargsによる後続処理によって1,000プロセスが順に起動してしまいます。
このような問題を回避するには、xargsの代わりにfindの-execオプションを使って一ファイルずつ処理するのが良いでしょう。これならば無駄にプロセスが生成されてリソースを消耗することはありません。
今回は以上です。参考になりましたら幸いです。