Linuxでファイルをコマンドラインで検索する方法
findコマンドの使い方
ストレージからファイルやディレクトリを検索するにはfindコマンドを使います。findコマンドの構文は
$ find 検索したい場所のパス オプション
findコマンドは「名前で検索」の他、「ファイルサイズ検索」「最終更新検索」などができます。
パスとしては
- / ルートディレクトリ
- . カレントディレクトリ
がよく使われます。ルートディレクトリの検索は幅広いので時間がかかるので指定方法に工夫が必要です。
名前で検索
シンプルでよく使う名前で検索には-nameオプションを使います。
$ find パス -name ファイル名
検索する名前はワイルドカードが使えます。ワイルドカードは\でエスケープする必要があります。
使用例
$ find /home/komeyan/ -name test
/home/komeyan/test
$ ls -l
total 0
drwxrwxrwx 1 komeyan komeyan 512 Jul 5 16:58 new
-rw-rw-rw- 1 komeyan komeyan 65 Jun 28 21:06 nout
drwxrwxrwx 1 komeyan komeyan 512 Jul 25 01:07 test
/home/komeyan/ディレクトリからtestというファイル・ディレクトリを検索しています。
使用例2 拡張子検索
拡張子の前にワイルドカード*を指定すれば指定した拡張子のファイルを検索することができます。ワイルドカード「*」は\でエスケープする必要があります。
$ find . -name \*.sh
./test.sh
./test2.sh
→カレントディレクトリから.shファイルを検索
日時指定検索
自動的に新しいファイルが自動で蓄積されるログファイルやメールファイルなどの場合、更新日時を指定すると目的のファイルを素早く、確実に検索できるようになります。
日時指定には
- -atime:最終アクセス日時
- -mtime:最終ファイル更新日時
があります。
アクセス日時指定 -atime
$ find パス -atime ひにち
というように指定します。ひにちは0が今日で1が昨日、7が一週間です。
- 1を指定した場合→最終アクセス日が昨日のファイル
- -1を指定した場合→最終アクセス日が今日から昨日までのファイル
- +1を指定した場合→最終アクセス日が昨日よりも前のファイル
分指定の -amin
日にちではなく分で指定したい場合は-aminを使います。基本は-atimeと同じです。- amin -10とすると今から10分前までにアクセスされたファイルを検索します。
更新日時検索 -mtime
$ find パス -mtime ひにち
基本は-atimeと同じです。アクセスではなく更新日時なのが違いです。
- 1を指定した場合→最終更新日が昨日のファイル
- -1を指定した場合→最終更新日が昨日から今日までのファイル
- +1を指定した場合→最終更新日が昨日よりも前のファイル
分指定の -mmin
-aminと同様に日にちではなく分で指定したい場合は-mminを使います。-10と指定すれば10分前までに更新されたファイルを検索します。
ファイルサイズの検索
ファイル容量を検索
$ find パス -size ファイルサイズ
分指定と同じく+(以上) -(以下) で指定の仕方が異なる。
$ find . -size +1000k
→カレントディレクトリで1000kバイト以上のファイルを検索
空ファイルの検索
$ find パス -empty
空ファイルを検索するオプションは-emptyです。
ファイルタイプの指定
$ find パス -type f(ファイル) or d (ディレクトリ)
findコマンドでは特に指定しないとファイルとディレクトリ両方を検索します。-typeオプションで指定すればファイルのみ及びディレクトリのみの検索が可能です。
複数の条件を指定 and or not
-orや-andを使うことによって複数条件検索も可能です。いずれかの条件にあてはまるものを検索したい場合は-orを、両方の条件を満たすものを検索したい場合は-andを使います。
$ find . -name \*.jpg -or -size +10k
$ find . -name \*.jpg -and -size +10k
エラーメッセージを/dev/nullに捨てる
findでは読み取りの権限が与えらえていない場所ではエラーメッセージが表示されて邪魔です。
$ find / -name \*.sh
find: ‘/mnt/c/Program Files/Windows Defender Advanced Threat Protection/Classification/Configuration’: Permission denied
/mnt/c/Program Files (x86)/VMware/VMware Workstation/tools-upgraders/run_upgrader.sh
そんなときはお決まりのエラーメッセージを捨てる出力リダイレクト「2>/dev/null」を使います。
$ find / -name \*.sh 2> /dev/null
/etc/console-setup/cached_setup_font.sh
検索するディレクトリの深さを指定 maxdepth
上位のディレクトリからファイルを検索すると何も指定しないとどんどん深いディレクトリまで検索します。しかし、実際は指定したディレクトリ内だけで良い事も多いです。その場合は-maxdepthで検索するディレクトリの深さを指定します。
-maxdepth 1でカレントディレクトリのみ、2で一つ下のディレクトリまで検索します。反対に-mindepthは指定したディレクトリよりも深いディレクトリを検索します。-mindepth 2で一つ下の階層よりも深い階層を検索します。
$ find /home -name \*.sh 2> /dev/null
/home/komeyan/test/test.sh
/home/komeyan/test/test2.sh
検索したファイルに対してコマンドの実行 -exec
検索したファイルに対して何らかのコマンド処理を実行したい場合は-execオプションを使います。
-execの後ろにコマンドを入力します。後ろの {} \;はとりあえず書くものだと思ってください。
$ find パス -option -exec コマンド {} \;
使用例
$ find . -name \*.sh -exec cat {} \;
これは~.shというファイルをカレントディレクトリで探し、catコマンドを実行してその中身を表示します。
バックスラッシュ(\ ¥)はセミコロンをエスケープするために入れています。
複数のコマンドを実行したい場合は -execを複数書く、
$ find . -name \*.sh -exec ls {} \; -exec cat {} \;
{}の後ろにセミコロン;ではなく+を書くと複数のfindコマンドによる検索結果をまとめてコマンドに渡します。
$ find . -name \*.sh -exec cat {} +
実際に違いを見てみましょう
$ find /home -name \*.sh -exec ls {} +
/home/komeyan/test/test.sh /home/komeyan/test/test2.sh
→一行にまとまって出力
$ find /home -name \*.sh -exec ls {} \;
/home/komeyan/test/test.sh
/home/komeyan/test/test2.sh
→別々に出力
-execと同じことはxargsコマンドを使ってもできます。
$ find /home -name \*.sh |xargs ls
/home/komeyan/test/test.sh /home/komeyan/test/test2.sh
→{} +と同じ結果に
locateコマンド
locateもfindと同じようにファイル検索ができるコマンドです。ファイルインデックスから検索するのでfindよりも高速に検索が可能です。
$ locate -i .bat
batファイルを検索します。-iオプションで大文字小文字の区別なく検索することができます。